Group :: Networking/File transfer
RPM: tftp
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: tftp-5.2-alt3.patch
Download
Download
tftp/main.c | 8 +++---
tftp/tftp.c | 16 +++++++----
tftpd/tftpd.8.in | 8 +++---
tftpd/tftpd.c | 82 ++++++++++++++++++++------------------------------------
4 files changed, 48 insertions(+), 66 deletions(-)
diff --git a/tftp/main.c b/tftp/main.c
index 1b8a881..b157c26 100644
--- a/tftp/main.c
+++ b/tftp/main.c
@@ -188,7 +188,7 @@ char *xstrdup(const char *);
const char *program;
-static inline void usage(int errcode)
+static void usage(int errcode)
{
fprintf(stderr,
#ifdef HAVE_IPV6
@@ -802,8 +802,10 @@ static void command(void)
line = NULL;
}
line = readline(prompt);
- if (!line)
- exit(0); /* EOF */
+ if (!line) { /* EOF */
+ putchar('\n');
+ exit(0);
+ }
#else
fputs(prompt, stdout);
if (fgets(line, LBUFLEN, stdin) == 0) {
diff --git a/tftp/tftp.c b/tftp/tftp.c
index d15da22..6270329 100644
--- a/tftp/tftp.c
+++ b/tftp/tftp.c
@@ -52,7 +52,7 @@ sigjmp_buf toplevel;
sigjmp_buf timeoutbuf;
static void nak(int, const char *);
-static int makerequest(int, const char *, struct tftphdr *, const char *);
+static int makerequest(int, const char *, void *, const char *);
static void printstats(const char *, unsigned long);
static void startclock(void);
static void stopclock(void);
@@ -276,17 +276,23 @@ void tftp_recvfile(int fd, const char *name, const char *mode)
static int
makerequest(int request, const char *name,
- struct tftphdr *tp, const char *mode)
+ void *p, const char *mode)
{
char *cp;
+ struct tftphdr *tp = p;
+ size_t namelen, modelen;
tp->th_opcode = htons((u_short) request);
- cp = (char *)&(tp->th_stuff);
+ cp = (char*)p + offsetof(struct tftphdr, th_stuff);
+ namelen = strlen(name);
+ modelen = strlen(mode);
+ if (namelen + modelen + 2 > SEGSIZE)
+ perror("Filename is too long");
strcpy(cp, name);
- cp += strlen(name);
+ cp += namelen;
*cp++ = '\0';
strcpy(cp, mode);
- cp += strlen(mode);
+ cp += modelen;
*cp++ = '\0';
return (cp - (char *)tp);
}
diff --git a/tftpd/tftpd.8.in b/tftpd/tftpd.8.in
index 78b4cfb..1a268a8 100644
--- a/tftpd/tftpd.8.in
+++ b/tftpd/tftpd.8.in
@@ -70,6 +70,9 @@ Similar to
but do not detach from the foreground process. Implies
.BR \-\-listen .
.TP
+\fB\-\-pid\fP, \fB\-P\fP
+Create pid file /var/run/tftpd.pid in standalone (listen) mode.
+.TP
\fB\-\-address\fP \fI[address][:port]\fP, \fB\-a\fP \fI[address][:port]\fP
Specify a specific
.I address
@@ -133,11 +136,6 @@ system-provided access controls for the user specified via the
.B \-\-user
option.
.TP
-\fB\-\-pidfile\fP \fIpidfile\fP, \fB\-P\fP \fIpidfile\fP
-When run in standalone mode, write the process ID of the listening
-server into \fIpidfile\fP. On normal termination (SIGTERM or SIGINT)
-the pid file is automatically removed.
-.TP
\fB\-\-timeout\fP \fItimeout\fP, \fB\-t\fP \fItimeout\fP
When run from
.B inetd
diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c
index 1873e70..d472ae5 100644
--- a/tftpd/tftpd.c
+++ b/tftpd/tftpd.c
@@ -145,13 +145,6 @@ static void handle_sighup(int sig)
caught_sighup = 1;
}
-/* Handle exit requests by SIGTERM and SIGINT */
-static volatile sig_atomic_t exit_signal = 0;
-static void handle_exit(int sig)
-{
- exit_signal = sig;
-}
-
/* Handle timeout signal or timeout event */
void timer(int sig)
{
@@ -346,10 +339,12 @@ static struct option long_options[] = {
{ "retransmit", 1, NULL, 'T' },
{ "port-range", 1, NULL, 'R' },
{ "map-file", 1, NULL, 'm' },
- { "pidfile", 1, NULL, 'P' },
+ { "pid", 1, NULL, 'P' },
{ NULL, 0, NULL, 0 }
};
-static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
+static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P";
+
+#define PIDFILE "/var/run/tftpd.pid"
int main(int argc, char **argv)
{
@@ -369,6 +364,7 @@ int main(int argc, char **argv)
int fdmax = 0;
int standalone = 0; /* Standalone (listen) mode */
int nodaemon = 0; /* Do not detach process */
+ int pidfile = 0; /* Create pid file */
char *address = NULL; /* Address to listen to */
pid_t pid;
mode_t my_umask = 0;
@@ -381,7 +377,6 @@ int main(int argc, char **argv)
#ifdef WITH_REGEX
char *rewrite_file = NULL;
#endif
- const char *pidfile = NULL;
u_short tp_opcode;
/* basename() is way too much of a pain from a portability standpoint */
@@ -506,7 +501,7 @@ int main(int argc, char **argv)
exit(0);
break;
case 'P':
- pidfile = optarg;
+ pidfile = 1;
break;
default:
syslog(LOG_ERR, "Unknown option: '%c'", optopt);
@@ -540,19 +535,16 @@ int main(int argc, char **argv)
exit(EX_NOUSER);
}
+ if (spec_umask || !unixperms)
+ umask(my_umask);
+
#ifdef WITH_REGEX
if (rewrite_file)
rewrite_rules = read_remap_rules(rewrite_file);
#endif
- if (pidfile && !standalone) {
- syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
- pidfile = NULL;
- }
-
/* If we're running standalone, set up the input port */
if (standalone) {
- FILE *pf;
#ifdef HAVE_IPV6
if (ai_fam != AF_INET6) {
#endif
@@ -560,14 +552,15 @@ int main(int argc, char **argv)
if (fd4 < 0) {
syslog(LOG_ERR, "cannot open IPv4 socket: %m");
exit(EX_OSERR);
- }
+ } else {
#ifndef __CYGWIN__
- set_socket_nonblock(fd4, 1);
+ set_socket_nonblock(fd4, 1);
#endif
- memset(&bindaddr4, 0, sizeof bindaddr4);
- bindaddr4.sin_family = AF_INET;
- bindaddr4.sin_addr.s_addr = INADDR_ANY;
- bindaddr4.sin_port = htons(IPPORT_TFTP);
+ memset(&bindaddr4, 0, sizeof bindaddr4);
+ bindaddr4.sin_family = AF_INET;
+ bindaddr4.sin_addr.s_addr = INADDR_ANY;
+ bindaddr4.sin_port = htons(IPPORT_TFTP);
+ }
#ifdef HAVE_IPV6
}
if (ai_fam != AF_INET) {
@@ -580,13 +573,14 @@ int main(int argc, char **argv)
syslog(LOG_ERR,
"cannot open IPv6 socket, disable IPv6: %m");
}
- }
+ } else {
#ifndef __CYGWIN__
- set_socket_nonblock(fd6, 1);
+ set_socket_nonblock(fd6, 1);
#endif
- memset(&bindaddr6, 0, sizeof bindaddr6);
- bindaddr6.sin6_family = AF_INET6;
- bindaddr6.sin6_port = htons(IPPORT_TFTP);
+ memset(&bindaddr6, 0, sizeof bindaddr6);
+ bindaddr6.sin6_family = AF_INET6;
+ bindaddr6.sin6_port = htons(IPPORT_TFTP);
+ }
}
#endif
if (address) {
@@ -737,20 +731,14 @@ int main(int argc, char **argv)
if (!nodaemon && daemon(secure, 0) < 0) {
syslog(LOG_ERR, "cannot daemonize: %m");
exit(EX_OSERR);
- }
- set_signal(SIGTERM, handle_exit, 0);
- set_signal(SIGINT, handle_exit, 0);
- if (pidfile) {
- pf = fopen (pidfile, "w");
- if (!pf) {
- syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile);
- pidfile = NULL;
- } else {
- if (fprintf(pf, "%d\n", getpid()) < 0)
- syslog(LOG_ERR, "error writing pid file '%s': %m", pidfile);
- if (fclose(pf))
- syslog(LOG_ERR, "error closing pid file '%s': %m", pidfile);
+#ifndef __CYGWIN__
+ } else if (pidfile) {
+ FILE* pidf = fopen(PIDFILE, "w");
+ if(pidf) {
+ fprintf(pidf, "%u\n", (unsigned int)getpid());
+ fclose(pidf);
}
+#endif
}
if (fd6 > fd4)
fdmax = fd6;
@@ -784,23 +772,11 @@ int main(int argc, char **argv)
lose packets as a result. */
set_signal(SIGHUP, handle_sighup, 0);
- if (spec_umask || !unixperms)
- umask(my_umask);
-
while (1) {
fd_set readset;
struct timeval tv_waittime;
int rv;
- if (exit_signal) { /* happens in standalone mode only */
- if (pidfile && unlink(pidfile)) {
- syslog(LOG_WARNING, "error removing pid file '%s': %m", pidfile);
- exit(EX_OSERR);
- } else {
- exit(0);
- }
- }
-
if (caught_sighup) {
caught_sighup = 0;
if (standalone) {