A couple of changes collected over the last year
authorWerner Koch <wk@gnupg.org>
Thu, 9 Mar 2006 15:36:31 +0000 (15:36 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 9 Mar 2006 15:36:31 +0000 (15:36 +0000)
BUGS
ChangeLog
NEWS
configure.in
src/config.h.in
src/error.h
src/ftp_listener.c
src/ftp_session.c
src/oftpd.c
src/oftpd.h

diff --git a/BUGS b/BUGS
index 64b69d6..ef5c177 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -23,6 +23,3 @@ $Id$
   not group-readable and someone in the group tries to read it they
   should not be allowed, apparently.  :(
 
   not group-readable and someone in the group tries to read it they
   should not be allowed, apparently.  :(
 
-- strerror() may not be thread safe (depends on implementation).  Write
-  a thread safe version.
-
index 0296e0b..f8d9ff1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-03-09  Werner Koch  <wk@g10code.de>
+
+       * configure.in: Define ERRBUF_SIZE.
+
+       * src/oftpd.c: Add option --version.
+
 2005-04-30  Werner Koch  <wk@g10code.de>
 
        Bumped version to 0.3.7-wk1.
 2005-04-30  Werner Koch  <wk@g10code.de>
 
        Bumped version to 0.3.7-wk1.
diff --git a/NEWS b/NEWS
index 5db7177..718106f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,10 @@
+Unreleased <wk@gnupg.org>
+
+  New option --version.
+
+  A couple of minor fixes.
+
+
 2003-08-13 <wk@gnupg.org>
 
   New option -r, --pasv-range to limit the range for passive ports to
 2003-08-13 <wk@gnupg.org>
 
   New option -r, --pasv-range to limit the range for passive ports to
index 5eaca5d..4370e1e 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT(src/file_list.c)
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT(src/file_list.c)
-AM_INIT_AUTOMAKE(oftpd, 0.3.7-wk1)
+AM_INIT_AUTOMAKE(oftpd, 0.3.7-wk2)
 AM_CONFIG_HEADER(src/config.h)
 
 dnl Checks for programs.
 AM_CONFIG_HEADER(src/config.h)
 
 dnl Checks for programs.
@@ -43,6 +43,7 @@ AC_FUNC_MEMCMP
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
 AC_CHECK_FUNCS(getcwd gettimeofday select socket strerror localtime_r gmtime_r)
 AC_TYPE_SIGNAL
 AC_FUNC_STRFTIME
 AC_CHECK_FUNCS(getcwd gettimeofday select socket strerror localtime_r gmtime_r)
+AC_CHECK_FUNCS(strerror_r)
 dnl AC_CHECK_LIB(pthread, pthread_create)
 dnl AC_SEARCH_LIBS(pthread_create, [ pthread pthreads thread threads ])
 AC_SEARCH_LIBS(socket, socket)
 dnl AC_CHECK_LIB(pthread, pthread_create)
 dnl AC_SEARCH_LIBS(pthread_create, [ pthread pthreads thread threads ])
 AC_SEARCH_LIBS(socket, socket)
@@ -104,6 +105,14 @@ dnl Check whether to enable IPv6 support
 AC_ARG_ENABLE([ipv6],[  --enable-ipv6           Enable IPv6 support (disabled by default)],
               CFLAGS="$CFLAGS -DINET6",)
 
 AC_ARG_ENABLE([ipv6],[  --enable-ipv6           Enable IPv6 support (disabled by default)],
               CFLAGS="$CFLAGS -DINET6",)
 
+
+AH_BOTTOM([
+/* Size of the buffer used for strerror_r. */
+#define ERRBUF_SIZE 256
+])
+
+
+
 AC_SUBST(HAVE_NEW_SS_FAMILY)
 AC_OUTPUT(Makefile src/Makefile man/Makefile)
 dnl AM_CONFIG_HEADER(src/config.h)
 AC_SUBST(HAVE_NEW_SS_FAMILY)
 AC_OUTPUT(Makefile src/Makefile man/Makefile)
 dnl AM_CONFIG_HEADER(src/config.h)
index cc00db2..bb6c04c 100644 (file)
@@ -70,6 +70,9 @@
 /* Define to 1 if you have the `strerror' function. */
 #undef HAVE_STRERROR
 
 /* Define to 1 if you have the `strerror' function. */
 #undef HAVE_STRERROR
 
+/* Define to 1 if you have the `strerror_r' function. */
+#undef HAVE_STRERROR_R
+
 /* Define to 1 if you have the `strftime' function. */
 #undef HAVE_STRFTIME
 
 /* Define to 1 if you have the `strftime' function. */
 #undef HAVE_STRFTIME
 
 
 /* Define to `unsigned' if <sys/types.h> does not define. */
 #undef size_t
 
 /* Define to `unsigned' if <sys/types.h> does not define. */
 #undef size_t
+
+
+/* Size of the buffer used for strerror_r. */
+#define ERRBUF_SIZE 256
+
index 04e69e0..3ac38f6 100644 (file)
@@ -15,4 +15,9 @@ void error_init(error_t *err, int error_code, const char *desc_fmt, ...);
 int error_get_error_code(const error_t *err);
 const char *error_get_desc(const error_t *err);
 
 int error_get_error_code(const error_t *err);
 const char *error_get_desc(const error_t *err);
 
+
+#ifndef HAVE_STRERROR_R
+char *strerror_r (int errnum, char *buf, size_t n);
+#endif
+
 #endif /* ERROR_H */
 #endif /* ERROR_H */
index 6a9d830..a5bab0e 100644 (file)
@@ -102,8 +102,9 @@ int ftp_listener_init(ftp_listener_t *f,
 
     /* get our current directory */
     if (getcwd(dir, sizeof(dir)) == NULL) {
 
     /* get our current directory */
     if (getcwd(dir, sizeof(dir)) == NULL) {
+        char errbuf[ERRBUF_SIZE];
         error_init(err, errno, "error getting current directory; %s",
         error_init(err, errno, "error getting current directory; %s",
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
         return 0;
     }
 
@@ -166,8 +167,9 @@ int ftp_listener_init(ftp_listener_t *f,
                               buf, 
                               sizeof(buf));
     if (inet_ntop_ret == NULL) {
                               buf, 
                               sizeof(buf));
     if (inet_ntop_ret == NULL) {
+        char errbuf[ERRBUF_SIZE];
         error_init(err, errno, "error converting server address to ASCII; %s", 
         error_init(err, errno, "error converting server address to ASCII; %s", 
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
     
         return 0;
     }
     
@@ -179,7 +181,9 @@ int ftp_listener_init(ftp_listener_t *f,
     /* okay, finally do some socket manipulation */
     fd = socket(AF_INET, SOCK_STREAM, 0);
     if (fd == -1) {
     /* okay, finally do some socket manipulation */
     fd = socket(AF_INET, SOCK_STREAM, 0);
     if (fd == -1) {
-        error_init(err, errno, "error creating socket; %s", strerror(errno));
+        char errbuf[ERRBUF_SIZE];
+        error_init(err, errno, "error creating socket; %s",
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
         return 0;
     }
 
@@ -187,47 +191,54 @@ int ftp_listener_init(ftp_listener_t *f,
     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, 
                    sizeof(int)) !=0) 
     {
     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuseaddr, 
                    sizeof(int)) !=0) 
     {
+        char errbuf[ERRBUF_SIZE];
         close(fd);
         error_init(err, errno, "error setting socket to reuse address; %s", 
         close(fd);
         error_init(err, errno, "error setting socket to reuse address; %s", 
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
     if (bind(fd, (struct sockaddr *)&sock_addr, 
              sizeof(struct sockaddr_in)) != 0) 
     {
         return 0;
     }
 
     if (bind(fd, (struct sockaddr *)&sock_addr, 
              sizeof(struct sockaddr_in)) != 0) 
     {
+        char errbuf[ERRBUF_SIZE];
         close(fd);
         close(fd);
-        error_init(err, errno, "error binding address; %s", strerror(errno));
+        error_init(err, errno, "error binding address; %s",
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
     if (listen(fd, SOMAXCONN) != 0) {
         return 0;
     }
 
     if (listen(fd, SOMAXCONN) != 0) {
+        char errbuf[ERRBUF_SIZE];
         close(fd);
         error_init(err, errno, "error setting socket to listen; %s", 
         close(fd);
         error_init(err, errno, "error setting socket to listen; %s", 
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
     /* prevent socket from blocking on accept() */
     flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
         return 0;
     }
 
     /* prevent socket from blocking on accept() */
     flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
+        char errbuf[ERRBUF_SIZE];
         close(fd);
         error_init(err, errno, "error getting flags on socket; %s", 
         close(fd);
         error_init(err, errno, "error getting flags on socket; %s", 
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
     if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
         return 0;
     }
     if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
+        char errbuf[ERRBUF_SIZE];
         close(fd);
         error_init(err, errno, "error setting socket to non-blocking; %s", 
         close(fd);
         error_init(err, errno, "error setting socket to non-blocking; %s", 
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
     /* create a pipe to wake up our listening thread */
     if (pipe(pipefds) != 0) {
         return 0;
     }
 
     /* create a pipe to wake up our listening thread */
     if (pipe(pipefds) != 0) {
+        char errbuf[ERRBUF_SIZE];
         close(fd);
         error_init(err, errno, "error creating pipe for internal use; %s", 
         close(fd);
         error_init(err, errno, "error creating pipe for internal use; %s", 
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
         return 0;
     }
 
         return 0;
     }
 
@@ -363,9 +374,10 @@ static void *connection_acceptor(ftp_listener_t *f)
              if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&tcp_nodelay,
                  sizeof(int)) != 0)
              {
              if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *)&tcp_nodelay,
                  sizeof(int)) != 0)
              {
+                 char errbuf[ERRBUF_SIZE];
                  syslog(LOG_ERR,
                    "error in setsockopt(), FTP server dropping connection; %s",
                  syslog(LOG_ERR,
                    "error in setsockopt(), FTP server dropping connection; %s",
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
                  close(fd);
                  continue;
              }
                  close(fd);
                  continue;
              }
@@ -374,9 +386,10 @@ static void *connection_acceptor(ftp_listener_t *f)
              if (getsockname(fd, (struct sockaddr *)&server_addr, 
                  &addr_len) == -1) 
              {
              if (getsockname(fd, (struct sockaddr *)&server_addr, 
                  &addr_len) == -1) 
              {
+                 char errbuf[ERRBUF_SIZE];
                  syslog(LOG_ERR, 
                    "error in getsockname(), FTP server dropping connection; %s",
                  syslog(LOG_ERR, 
                    "error in getsockname(), FTP server dropping connection; %s",
-                   strerror(errno));
+                   strerror_r(errno, errbuf, ERRBUF_SIZE));
                  close(fd);
                  continue;
              }
                  close(fd);
                  continue;
              }
@@ -423,14 +436,15 @@ static void *connection_acceptor(ftp_listener_t *f)
 
              num_error = 0;
          } else {
 
              num_error = 0;
          } else {
+             char errbuf[ERRBUF_SIZE];
              if ((errno == ECONNABORTED) || (errno == ECONNRESET)) {
                  syslog(LOG_NOTICE, 
                      "interruption accepting FTP connection; %s", 
              if ((errno == ECONNABORTED) || (errno == ECONNRESET)) {
                  syslog(LOG_NOTICE, 
                      "interruption accepting FTP connection; %s", 
-                     strerror(errno));
+                     strerror_r(errno, errbuf, ERRBUF_SIZE));
              } else {
                  syslog(LOG_WARNING, 
                      "error accepting FTP connection; %s", 
              } else {
                  syslog(LOG_WARNING, 
                      "error accepting FTP connection; %s", 
-                     strerror(errno));
+                     strerror_r(errno, errbuf, ERRBUF_SIZE));
                  /* We don't bump the error counter if we are merely
                     out of file descriptors.  The hope is that some
                     other thread will eventually finish and release
                  /* We don't bump the error counter if we are merely
                     out of file descriptors.  The hope is that some
                     other thread will eventually finish and release
index 1bf780a..7622936 100644 (file)
@@ -150,8 +150,9 @@ int ftp_session_init(ftp_session_t *f,
         hints.ai_family = AF_INET;
        hints.ai_flags = AI_PASSIVE;
        if (getaddrinfo(NULL, "ftp", &hints, &res) != 0) {
         hints.ai_family = AF_INET;
        hints.ai_flags = AI_PASSIVE;
        if (getaddrinfo(NULL, "ftp", &hints, &res) != 0) {
+            char errbuf[ERRBUF_SIZE];
            error_init(err, 0, "unable to determing IPv4 address; %s",
            error_init(err, 0, "unable to determing IPv4 address; %s",
-               gai_strerror(errcode));
+               gai_strerror_r(errcode, errbuf, ERRBUF_SIZE));
            return 0;
        }
 
            return 0;
        }
 
@@ -729,7 +730,9 @@ static int set_pasv(ftp_session_t *f, sockaddr_storage_t *bind_addr)
 
     socket_fd = socket(SSFAM(bind_addr), SOCK_STREAM, 0);
     if (socket_fd == -1) {
 
     socket_fd = socket(SSFAM(bind_addr), SOCK_STREAM, 0);
     if (socket_fd == -1) {
-        reply(f, 500, "Error creating server socket; %s.", strerror(errno));
+        char errbuf[ERRBUF_SIZE];
+        reply(f, 500, "Error creating server socket; %s.",
+              strerror_r(errno, errbuf, ERRBUF_SIZE));
        return -1;
     } 
 
        return -1;
     } 
 
@@ -742,14 +745,18 @@ static int set_pasv(ftp_session_t *f, sockaddr_storage_t *bind_addr)
            break;
        }
        if (errno != EADDRINUSE) {
            break;
        }
        if (errno != EADDRINUSE) {
-            reply(f, 500, "Error binding server port; %s.", strerror(errno));
+            char errbuf[ERRBUF_SIZE];
+            reply(f, 500, "Error binding server port; %s.",
+                  strerror_r(errno, errbuf, ERRBUF_SIZE));
             close(socket_fd);
             return -1;
        }
     }
 
     if (listen(socket_fd, 1) != 0) {
             close(socket_fd);
             return -1;
        }
     }
 
     if (listen(socket_fd, 1) != 0) {
-        reply(f, 500, "Error listening on server port; %s.", strerror(errno));
+        char errbuf[ERRBUF_SIZE];
+        reply(f, 500, "Error listening on server port; %s.",
+              strerror_r(errno, errbuf, ERRBUF_SIZE));
         close(socket_fd);
        return -1;
     }
         close(socket_fd);
        return -1;
     }
@@ -1086,6 +1093,7 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
     off_t amt_to_send;
     int sendfile_ret;
     off_t amt_sent;
     off_t amt_to_send;
     int sendfile_ret;
     off_t amt_sent;
+    char errbuf[ERRBUF_SIZE];
 
     daemon_assert(invariant(f));
     daemon_assert(cmd != NULL);
 
     daemon_assert(invariant(f));
     daemon_assert(cmd != NULL);
@@ -1107,11 +1115,13 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
     else
       file_fd = open(full_path, O_RDONLY);
     if (file_fd == -1) {
     else
       file_fd = open(full_path, O_RDONLY);
     if (file_fd == -1) {
-        reply(f, 550, "Error opening file; %s.", strerror(errno));
+        reply(f, 550, "Error opening file; %s.",
+              strerror_r(errno, errbuf, ERRBUF_SIZE));
        goto exit_retr;
     }
     if (fstat(file_fd, &stat_buf) != 0) {
        goto exit_retr;
     }
     if (fstat(file_fd, &stat_buf) != 0) {
-        reply(f, 550, "Error getting file information; %s.", strerror(errno));
+        reply(f, 550, "Error getting file information; %s.",
+              strerror_r(errno, errbuf, ERRBUF_SIZE));
        goto exit_retr;
     }
 #ifndef STATS_MACRO_BROKEN
        goto exit_retr;
     }
 #ifndef STATS_MACRO_BROKEN
@@ -1130,7 +1140,7 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
     {
        if (lseek(file_fd, f->file_offset, SEEK_SET) == -1) {
            reply(f, 550, "Error seeking to restart position; %s.", 
     {
        if (lseek(file_fd, f->file_offset, SEEK_SET) == -1) {
            reply(f, 550, "Error seeking to restart position; %s.", 
-               strerror(errno));
+               strerror_r(errno, errbuf, ERRBUF_SIZE));
             goto exit_retr;
        }
     }
             goto exit_retr;
        }
     }
@@ -1153,7 +1163,8 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
         for (;;) {
             read_ret = read(file_fd, buf, sizeof(buf));
            if (read_ret == -1) {
         for (;;) {
             read_ret = read(file_fd, buf, sizeof(buf));
            if (read_ret == -1) {
-               reply(f, 550, "Error reading from file; %s.", strerror(errno));
+               reply(f, 550, "Error reading from file; %s.",
+                      strerror_r(errno, errbuf, ERRBUF_SIZE));
                goto exit_retr;
            }
            if (read_ret == 0) {
                goto exit_retr;
            }
            if (read_ret == 0) {
@@ -1163,7 +1174,7 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
 
             if (write_fully(socket_fd, converted_buf, converted_buflen) == -1) {
                 reply(f, 550, "Error writing to data connection; %s.", 
 
             if (write_fully(socket_fd, converted_buf, converted_buflen) == -1) {
                 reply(f, 550, "Error writing to data connection; %s.", 
-                 strerror(errno));
+                 strerror_r(errno, errbuf, ERRBUF_SIZE));
                 goto exit_retr;
             }
 
                 goto exit_retr;
             }
 
@@ -1190,7 +1201,8 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
                                     &offset, 
                                     amt_to_send);
             if (sendfile_ret != amt_to_send) {
                                     &offset, 
                                     amt_to_send);
             if (sendfile_ret != amt_to_send) {
-                reply(f, 550, "Error sending file; %s.", strerror(errno));
+                reply(f, 550, "Error sending file; %s.",
+                      strerror_r(errno, errbuf, ERRBUF_SIZE));
                 goto exit_retr;
             }
 #elif HAVE_FREEBSD_SENDFILE
                 goto exit_retr;
             }
 #elif HAVE_FREEBSD_SENDFILE
@@ -1202,7 +1214,8 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
                                     &amt_sent,
                                     0);
             if (sendfile_ret != 0) {
                                     &amt_sent,
                                     0);
             if (sendfile_ret != 0) {
-                reply(f, 550, "Error sending file; %s.", strerror(errno));
+                reply(f, 550, "Error sending file; %s.",
+                      strerror_r(errno, errbuf, ERRBUF_SIZE));
                 goto exit_retr;
             }
             offset += amt_sent;
                 goto exit_retr;
             }
             offset += amt_sent;
@@ -1214,7 +1227,8 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
         for (;;) {
             read_ret = read(file_fd, buf, sizeof(buf));
            if (read_ret == -1) {
         for (;;) {
             read_ret = read(file_fd, buf, sizeof(buf));
            if (read_ret == -1) {
-               reply(f, 550, "Error reading from file; %s.", strerror(errno));
+               reply(f, 550, "Error reading from file; %s.",
+                      strerror_r(errno, errbuf, ERRBUF_SIZE));
                goto exit_retr;
            }
            if (read_ret == 0) {
                goto exit_retr;
            }
            if (read_ret == 0) {
@@ -1222,7 +1236,7 @@ static void do_retr(ftp_session_t *f, const ftp_command_t *cmd)
            }
            if (write_fully(socket_fd, buf, read_ret) == -1) {
                reply(f, 550, "Error writing to data connection; %s.", 
            }
            if (write_fully(socket_fd, buf, read_ret) == -1) {
                reply(f, 550, "Error writing to data connection; %s.", 
-                 strerror(errno));
+                 strerror_r(errno, errbuf, ERRBUF_SIZE));
                goto exit_retr;
            }
             file_size += read_ret;
                goto exit_retr;
            }
             file_size += read_ret;
@@ -1290,6 +1304,7 @@ static int open_connection(ftp_session_t *f)
     int socket_fd;
     struct sockaddr_in addr;
     unsigned addr_len;
     int socket_fd;
     struct sockaddr_in addr;
     unsigned addr_len;
+    char errbuf[ERRBUF_SIZE];
 
     daemon_assert((f->data_channel == DATA_PORT) || 
                   (f->data_channel == DATA_PASSIVE));
 
     daemon_assert((f->data_channel == DATA_PORT) || 
                   (f->data_channel == DATA_PASSIVE));
@@ -1297,13 +1312,15 @@ static int open_connection(ftp_session_t *f)
     if (f->data_channel == DATA_PORT) {
         socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0);
        if (socket_fd == -1) {
     if (f->data_channel == DATA_PORT) {
         socket_fd = socket(SSFAM(&f->data_port), SOCK_STREAM, 0);
        if (socket_fd == -1) {
-           reply(f, 425, "Error creating socket; %s.", strerror(errno));
+           reply(f, 425, "Error creating socket; %s.",
+                  strerror_r(errno, errbuf, ERRBUF_SIZE));
            return -1;
        }
        if (connect(socket_fd, (struct sockaddr *)&f->data_port, 
            sizeof(sockaddr_storage_t)) != 0)
        {
            return -1;
        }
        if (connect(socket_fd, (struct sockaddr *)&f->data_port, 
            sizeof(sockaddr_storage_t)) != 0)
        {
-           reply(f, 425, "Error connecting; %s.", strerror(errno));
+           reply(f, 425, "Error connecting; %s.",
+                  strerror_r(errno, errbuf, ERRBUF_SIZE));
            close(socket_fd);
            return -1;
        }
            close(socket_fd);
            return -1;
        }
@@ -1313,7 +1330,8 @@ static int open_connection(ftp_session_t *f)
         addr_len = sizeof(struct sockaddr_in);
         socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len);
        if (socket_fd == -1) {
         addr_len = sizeof(struct sockaddr_in);
         socket_fd = accept(f->server_fd, (struct sockaddr *)&addr, &addr_len);
        if (socket_fd == -1) {
-           reply(f, 425, "Error accepting connection; %s.", strerror(errno));
+           reply(f, 425, "Error accepting connection; %s.",
+                  strerror_r(errno, errbuf, ERRBUF_SIZE));
            return -1;
        }
 #ifdef INET6
            return -1;
        }
 #ifdef INET6
@@ -1628,6 +1646,7 @@ static void do_size(ftp_session_t *f, const ftp_command_t *cmd)
     const char *file_name;
     char full_path[PATH_MAX+1+MAX_STRING_LEN];
     struct stat stat_buf;
     const char *file_name;
     char full_path[PATH_MAX+1+MAX_STRING_LEN];
     struct stat stat_buf;
+    char errbuf[ERRBUF_SIZE];
     
     daemon_assert(invariant(f));
     daemon_assert(cmd != NULL);
     
     daemon_assert(invariant(f));
     daemon_assert(cmd != NULL);
@@ -1646,10 +1665,12 @@ static void do_size(ftp_session_t *f, const ftp_command_t *cmd)
         if (!strncmp (full_path, "/dev", 4)
             && (!full_path[4] || full_path[4] == '/')) {
             errno = ENOENT;
         if (!strncmp (full_path, "/dev", 4)
             && (!full_path[4] || full_path[4] == '/')) {
             errno = ENOENT;
-            reply(f, 550, "Error getting file status; %s.", strerror(errno));
+            reply(f, 550, "Error getting file status; %s.",
+                  strerror_r(errno, errbuf, ERRBUF_SIZE));
         }
         else if (stat(full_path, &stat_buf) != 0) {
         }
         else if (stat(full_path, &stat_buf) != 0) {
-            reply(f, 550, "Error getting file status; %s.", strerror(errno));
+            reply(f, 550, "Error getting file status; %s.",
+                  strerror_r(errno, errbuf, ERRBUF_SIZE));
         }
         else if (S_ISDIR(stat_buf.st_mode)) {
             reply(f, 550, "File is a directory, SIZE command not valid.");
         }
         else if (S_ISDIR(stat_buf.st_mode)) {
             reply(f, 550, "File is a directory, SIZE command not valid.");
@@ -1687,6 +1708,7 @@ static void do_mdtm(ftp_session_t *f, const ftp_command_t *cmd)
     struct stat stat_buf;
     struct tm mtime;
     char time_buf[16];
     struct stat stat_buf;
     struct tm mtime;
     char time_buf[16];
+    char errbuf[ERRBUF_SIZE];
     
     daemon_assert(invariant(f));
     daemon_assert(cmd != NULL);
     
     daemon_assert(invariant(f));
     daemon_assert(cmd != NULL);
@@ -1700,10 +1722,12 @@ static void do_mdtm(ftp_session_t *f, const ftp_command_t *cmd)
     if (!strncmp (full_path, "/dev", 4)
         && (!full_path[4] || full_path[4] == '/')) {
         errno = ENOENT;
     if (!strncmp (full_path, "/dev", 4)
         && (!full_path[4] || full_path[4] == '/')) {
         errno = ENOENT;
-        reply(f, 550, "Error getting file status; %s.", strerror(errno));
+        reply(f, 550, "Error getting file status; %s.",
+              strerror_r(errno, errbuf, ERRBUF_SIZE));
     }
     else if (stat(full_path, &stat_buf) != 0) {
     }
     else if (stat(full_path, &stat_buf) != 0) {
-        reply(f, 550, "Error getting file status; %s.", strerror(errno));
+        reply(f, 550, "Error getting file status; %s.",
+              strerror_r(errno, errbuf, ERRBUF_SIZE));
     } else {
         gmtime_r(&stat_buf.st_mtime, &mtime);
         strftime(time_buf, sizeof(time_buf), "%Y%m%d%H%M%S", &mtime);
     } else {
         gmtime_r(&stat_buf.st_mtime, &mtime);
         strftime(time_buf, sizeof(time_buf), "%Y%m%d%H%M%S", &mtime);
index 9beb16e..d5dd2bc 100644 (file)
@@ -47,6 +47,7 @@ int main(int argc, char *argv[])
     char *address;
     
     char temp_buf[256];
     char *address;
     
     char temp_buf[256];
+    char errbuf[ERRBUF_SIZE];
 
     struct passwd *user_info;
     error_t err;
 
     struct passwd *user_info;
     error_t err;
@@ -67,8 +68,13 @@ int main(int argc, char *argv[])
 
     /* verify we're running as root */
     if (geteuid() != 0) {
 
     /* verify we're running as root */
     if (geteuid() != 0) {
+        if ( argc > 1 && !strcmp (argv[1], "--version")) {
+                printf ("%s %s\n", PACKAGE, VERSION);
+                exit (0);
+        }
         fprintf(stderr, "%s: program needs root permission to run\n", exe_name);
         exit(1);
         fprintf(stderr, "%s: program needs root permission to run\n", exe_name);
         exit(1);
+
     }
 
     /* default command-line arguments */
     }
 
     /* default command-line arguments */
@@ -198,6 +204,9 @@ int main(int argc, char *argv[])
                         log_facility = LOG_LOCAL7;
                         break;
                 }
                         log_facility = LOG_LOCAL7;
                         break;
                 }
+            } else if (strcmp(argv[i], "--version") == 0) {
+                printf ("%s %s\n", PACKAGE, VERSION);
+                exit (0);
             } else {
                 print_usage("unknown option");
                 exit(1);
             } else {
                 print_usage("unknown option");
                 exit(1);
@@ -241,11 +250,12 @@ int main(int argc, char *argv[])
     /* change to root directory */
     if (chroot(dir_ptr) != 0) {
         syslog(LOG_ERR, "error with root directory; %s\n", exe_name, 
     /* change to root directory */
     if (chroot(dir_ptr) != 0) {
         syslog(LOG_ERR, "error with root directory; %s\n", exe_name, 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     if (chdir("/") != 0) {
         exit(1);
     }
     if (chdir("/") != 0) {
-        syslog(LOG_ERR, "error changing directory; %s\n", strerror(errno));
+        syslog(LOG_ERR, "error changing directory; %s\n",
+               strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
 
         exit(1);
     }
 
@@ -256,7 +266,7 @@ int main(int argc, char *argv[])
 
       if (stat( "/dev", &stat_buf)) {
         syslog (LOG_ERR, "required `%s/dev' directory is missing: %s\n",
 
       if (stat( "/dev", &stat_buf)) {
         syslog (LOG_ERR, "required `%s/dev' directory is missing: %s\n",
-                dir_ptr, strerror (errno));
+                dir_ptr, strerror_r (errno, errbuf, ERRBUF_SIZE));
       }
 #ifndef STATS_MACRO_BROKEN
       if (!S_ISDIR(stat_buf.st_mode)) {
       }
 #ifndef STATS_MACRO_BROKEN
       if (!S_ISDIR(stat_buf.st_mode)) {
@@ -283,11 +293,13 @@ int main(int argc, char *argv[])
 
     /* set user to be as inoffensive as possible */
     if (setgid(user_info->pw_gid) != 0) {
 
     /* set user to be as inoffensive as possible */
     if (setgid(user_info->pw_gid) != 0) {
-        syslog(LOG_ERR, "error changing group; %s", strerror(errno));
+        syslog(LOG_ERR, "error changing group; %s",
+               strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     if (setuid(user_info->pw_uid) != 0) {
         exit(1);
     }
     if (setuid(user_info->pw_uid) != 0) {
-        syslog(LOG_ERR, "error changing group; %s", strerror(errno));
+        syslog(LOG_ERR, "error changing group; %s",
+               strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
 
         exit(1);
     }
 
@@ -341,25 +353,27 @@ static void daemonize()
     int max_fd;
     int null_fd;
     int fd;
     int max_fd;
     int null_fd;
     int fd;
+    char errbuf[ERRBUF_SIZE];
 
     null_fd = open("/dev/null", O_RDWR);
     if (null_fd == -1) {
         fprintf(stderr, "%s: error opening null output device; %s\n", exe_name, 
 
     null_fd = open("/dev/null", O_RDWR);
     if (null_fd == -1) {
         fprintf(stderr, "%s: error opening null output device; %s\n", exe_name, 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
 
     max_fd = sysconf(_SC_OPEN_MAX);
     if (max_fd == -1) {
         fprintf(stderr, "%s: error getting maximum open file; %s\n", exe_name, 
         exit(1);
     }
 
     max_fd = sysconf(_SC_OPEN_MAX);
     if (max_fd == -1) {
         fprintf(stderr, "%s: error getting maximum open file; %s\n", exe_name, 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
 
 
     fork_ret = fork();
     if (fork_ret == -1) {
         exit(1);
     }
 
 
     fork_ret = fork();
     if (fork_ret == -1) {
-        fprintf(stderr, "%s: error forking; %s\n", exe_name, strerror(errno));
+        fprintf(stderr, "%s: error forking; %s\n",
+                exe_name, strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     if (fork_ret != 0) {
         exit(1);
     }
     if (fork_ret != 0) {
@@ -367,12 +381,13 @@ static void daemonize()
     }
     if (setsid() == -1) {
         fprintf(stderr, "%s: error creating process group; %s\n", exe_name, 
     }
     if (setsid() == -1) {
         fprintf(stderr, "%s: error creating process group; %s\n", exe_name, 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     fork_ret = fork();
     if (fork_ret == -1) {
         exit(1);
     }
     fork_ret = fork();
     if (fork_ret == -1) {
-        fprintf(stderr, "%s: error forking; %s\n", exe_name, strerror(errno));
+        fprintf(stderr, "%s: error forking; %s\n",
+                exe_name, strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     if (fork_ret != 0) {
         exit(1);
     }
     if (fork_ret != 0) {
@@ -380,17 +395,17 @@ static void daemonize()
     }
     if (dup2(null_fd, 0) == -1) {
         syslog(LOG_ERR, "error setting input to null; %s", 
     }
     if (dup2(null_fd, 0) == -1) {
         syslog(LOG_ERR, "error setting input to null; %s", 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     if (dup2(null_fd, 1) == -1) {
         syslog(LOG_ERR, "error setting output to null; %s", 
         exit(1);
     }
     if (dup2(null_fd, 1) == -1) {
         syslog(LOG_ERR, "error setting output to null; %s", 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     if (dup2(null_fd, 2) == -1) {
         syslog(LOG_ERR, "error setting error output to null; %s", 
         exit(1);
     }
     if (dup2(null_fd, 2) == -1) {
         syslog(LOG_ERR, "error setting error output to null; %s", 
-          strerror(errno));
+          strerror_r(errno, errbuf, ERRBUF_SIZE));
         exit(1);
     }
     for (fd=3; fd<max_fd; fd++) {
         exit(1);
     }
     for (fd=3; fd<max_fd; fd++) {
index 0e4dc3c..2facb6d 100644 (file)
@@ -28,6 +28,5 @@
 /* README file name (sent automatically as a response to users) */
 #define README_FILE_NAME "README"
 
 /* README file name (sent automatically as a response to users) */
 #define README_FILE_NAME "README"
 
-
 #endif /* OFTPD_H */
 
 #endif /* OFTPD_H */