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) {