* keyboard.c (read_key_sequence): Don't check last_real_key_start redundantly.
[bpt/emacs.git] / lib-src / movemail.c
index 4ccdc93..4a894c1 100644 (file)
@@ -1,7 +1,8 @@
 /* movemail foo bar -- move file foo to file bar,
    locking file foo the way /bin/mail respects.
-   Copyright (C) 1986, 1992, 1993, 1994, 1996, 1999, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
+
+Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2011
+  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -63,9 +64,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <time.h>
 
 #include <getopt.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
 #endif
@@ -81,13 +80,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #undef access
 #endif /* MSDOS */
 
-#ifndef DIRECTORY_SEP
-#define DIRECTORY_SEP '/'
-#endif
-#ifndef IS_DIRECTORY_SEP
-#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
-#endif
-
 #ifdef WINDOWSNT
 #include "ntlib.h"
 #undef access
@@ -162,15 +154,15 @@ static int mbx_delimit_end (FILE *mbf);
 #endif
 
 /* Nonzero means this is name of a lock file to delete on fatal error.  */
-char *delete_lockname;
+static char *delete_lockname;
 
 int
 main (int argc, char **argv)
 {
   char *inname, *outname;
   int indesc, outdesc;
-  int nread;
-  int status;
+  ssize_t nread;
+  int wait_status;
   int c, preserve_mail = 0;
 
 #ifndef MAIL_USE_SYSTEM_LOCK
@@ -270,6 +262,13 @@ main (int argc, char **argv)
   if (! spool_name)
 #endif
     {
+      #ifndef DIRECTORY_SEP
+       #define DIRECTORY_SEP '/'
+      #endif
+      #ifndef IS_DIRECTORY_SEP
+       #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
+      #endif
+
       /* Use a lock file named after our first argument with .lock appended:
         If it exists, the mail file is locked.  */
       /* Note: this locking mechanism is *required* by the mailer
@@ -356,7 +355,7 @@ main (int argc, char **argv)
       time_t touched_lock, now;
 #endif
 
-      if (setuid (getuid ()) < 0 || setegid (real_gid) < 0)
+      if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0)
        fatal ("Failed to drop privileges", 0, 0);
 
 #ifndef MAIL_USE_MMDF
@@ -383,7 +382,7 @@ main (int argc, char **argv)
       if (outdesc < 0)
        pfatal_with_name (outname);
 
-      if (setegid (priv_gid) < 0)
+      if (setregid (-1, priv_gid) < 0)
        fatal ("Failed to regain privileges", 0, 0);
 
       /* This label exists so we can retry locking
@@ -480,7 +479,7 @@ main (int argc, char **argv)
 #endif
 
       /* Prevent symlink attacks truncating other users' mailboxes */
-      if (setegid (real_gid) < 0)
+      if (setregid (-1, real_gid) < 0)
        fatal ("Failed to drop privileges", 0, 0);
 
       /* Check to make sure no errors before we zap the inbox.  */
@@ -490,7 +489,8 @@ main (int argc, char **argv)
 #ifdef MAIL_USE_SYSTEM_LOCK
       if (! preserve_mail)
        {
-         ftruncate (indesc, 0L);
+         if (ftruncate (indesc, 0L) != 0)
+           pfatal_with_name (inname);
        }
 #endif /* MAIL_USE_SYSTEM_LOCK */
 
@@ -515,7 +515,7 @@ main (int argc, char **argv)
 #endif /* not MAIL_USE_SYSTEM_LOCK */
 
       /* End of mailbox truncation */
-      if (setegid (priv_gid) < 0)
+      if (setregid (-1, priv_gid) < 0)
        fatal ("Failed to regain privileges", 0, 0);
 
 #ifdef MAIL_USE_MAILLOCK
@@ -527,11 +527,11 @@ main (int argc, char **argv)
       exit (EXIT_SUCCESS);
     }
 
-  wait (&status);
-  if (!WIFEXITED (status))
+  wait (&wait_status);
+  if (!WIFEXITED (wait_status))
     exit (EXIT_FAILURE);
-  else if (WRETCODE (status) != 0)
-    exit (WRETCODE (status));
+  else if (WRETCODE (wait_status) != 0)
+    exit (WRETCODE (wait_status));
 
 #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK)
 #ifdef MAIL_USE_MAILLOCK
@@ -551,8 +551,7 @@ main (int argc, char **argv)
    string-comparing the two paths, because one or both of them might
    be symbolic links pointing to some other directory. */
 static char *
-mail_spool_name (inname)
-     char *inname;
+mail_spool_name (char *inname)
 {
   struct stat stat1, stat2;
   char *indir, *fname;
@@ -632,7 +631,7 @@ pfatal_and_delete (char *name)
 static char *
 concat (const char *s1, const char *s2, const char *s3)
 {
-  int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
+  size_t len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
   char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
 
   strcpy (result, s1);
@@ -671,14 +670,8 @@ xmalloc (unsigned int size)
 
 #define NOTOK (-1)
 #define OK 0
-#define DONE 1
-
-char *progname;
-FILE *sfi;
-FILE *sfo;
-char ibuffer[BUFSIZ];
-char obuffer[BUFSIZ];
-char Errmsg[200];              /* POP errors, at least, can exceed
+
+static char Errmsg[200];       /* POP errors, at least, can exceed
                                   the original length of 80.  */
 
 /*
@@ -737,7 +730,18 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse
       error ("Error in open: %s, %s", strerror (errno), outfile);
       return EXIT_FAILURE;
     }
-  fchown (mbfi, getuid (), -1);
+
+  if (fchown (mbfi, getuid (), -1) != 0)
+    {
+      int fchown_errno = errno;
+      struct stat st;
+      if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ())
+       {
+         pop_close (server);
+         error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile);
+         return EXIT_FAILURE;
+       }
+    }
 
   if ((mbf = fdopen (mbfi, "wb")) == NULL)
     {
@@ -829,10 +833,10 @@ pop_retr (popserver server, int msgno, FILE *arg)
 
   if (pop_retrieve_first (server, msgno, &line))
     {
-      char *error = concat ("Error from POP server: ", pop_error, "");
-      strncpy (Errmsg, error, sizeof (Errmsg));
+      char *msg = concat ("Error from POP server: ", pop_error, "");
+      strncpy (Errmsg, msg, sizeof (Errmsg));
       Errmsg[sizeof (Errmsg)-1] = '\0';
-      free(error);
+      free (msg);
       return (NOTOK);
     }
 
@@ -851,27 +855,26 @@ pop_retr (popserver server, int msgno, FILE *arg)
 
   if (ret)
     {
-      char *error = concat ("Error from POP server: ", pop_error, "");
-      strncpy (Errmsg, error, sizeof (Errmsg));
+      char *msg = concat ("Error from POP server: ", pop_error, "");
+      strncpy (Errmsg, msg, sizeof (Errmsg));
       Errmsg[sizeof (Errmsg)-1] = '\0';
-      free(error);
+      free (msg);
       return (NOTOK);
     }
 
   return (OK);
 }
 
-/* Do this as a macro instead of using strcmp to save on execution time. */
-#define IS_FROM_LINE(a) ((a[0] == 'F') \
-                        && (a[1] == 'r') \
-                        && (a[2] == 'o') \
-                        && (a[3] == 'm') \
-                        && (a[4] == ' '))
-
 static int
 mbx_write (char *line, int len, FILE *mbf)
 {
 #ifdef MOVEMAIL_QUOTE_POP_FROM_LINES
+  /* Do this as a macro instead of using strcmp to save on execution time. */
+  # define IS_FROM_LINE(a) ((a[0] == 'F')      \
+                           && (a[1] == 'r')    \
+                           && (a[2] == 'o')    \
+                           && (a[3] == 'm')    \
+                           && (a[4] == ' '))
   if (IS_FROM_LINE (line))
     {
       if (fputc ('>', mbf) == EOF)
@@ -934,7 +937,5 @@ strerror (errnum)
 
 #endif /* ! HAVE_STRERROR */
 
-/* arch-tag: 1c323112-41fe-4fe5-8de9-494de631f73f
-   (do not change this comment) */
 
 /* movemail.c ends here */