lisp/gnus/auth-source.el (auth-source-netrc-parse-one): Allow empty strings in authin...
[bpt/emacs.git] / lib-src / movemail.c
index b9a1be8..81ac8aa 100644 (file)
@@ -1,8 +1,8 @@
 /* movemail foo bar -- move file foo to file bar,
    locking file foo the way /bin/mail respects.
 
-Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2012
-  Free Software Foundation, Inc.
+Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2013 Free Software
+Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -22,7 +22,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Important notice: defining MAIL_USE_FLOCK or MAIL_USE_LOCKF *will
    cause loss of mail* if you do it on a system that does not normally
-   use flock as its way of interlocking access to inbox files.  The
+   use flock/lockf as its way of interlocking access to inbox files.  The
    setting of MAIL_USE_FLOCK and MAIL_USE_LOCKF *must agree* with the
    system's own conventions.  It is not a choice that is up to you.
 
@@ -65,9 +65,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <getopt.h>
 #include <unistd.h>
-#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
-#endif
 #include <string.h>
 #include "syswait.h"
 #ifdef MAIL_USE_POP
@@ -98,17 +96,15 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <fcntl.h>
 #endif /* WINDOWSNT */
 
-#ifndef F_OK
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-#endif
-
 #ifdef WINDOWSNT
 #include <sys/locking.h>
 #endif
 
+/* If your system uses the `flock' or `lockf' system call for mail locking,
+   define MAIL_USE_SYSTEM_LOCK.  If your system type should always define
+   MAIL_USE_LOCKF or MAIL_USE_FLOCK but configure does not do this,
+   please make a bug report.  */
+
 #ifdef MAIL_USE_LOCKF
 #define MAIL_USE_SYSTEM_LOCK
 #endif
@@ -133,17 +129,10 @@ static char *mail_spool_name (char *);
 #endif
 #endif
 
-#ifndef HAVE_STRERROR
-char *strerror (int);
-#endif
-
 static _Noreturn void fatal (const char *s1, const char *s2, const char *s3);
 static void error (const char *s1, const char *s2, const char *s3);
 static _Noreturn void pfatal_with_name (char *name);
 static _Noreturn void pfatal_and_delete (char *name);
-#ifdef MAIL_USE_MAILLOCK
-static void *xmalloc (size_t size);
-#endif
 #ifdef MAIL_USE_POP
 static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order);
 static int pop_retr (popserver server, int msgno, FILE *arg);
@@ -152,6 +141,21 @@ static int mbx_delimit_begin (FILE *mbf);
 static int mbx_delimit_end (FILE *mbf);
 #endif
 
+#if (defined MAIL_USE_MAILLOCK                                         \
+     || (!defined DISABLE_DIRECT_ACCESS && !defined MAIL_USE_MMDF      \
+        && !defined MAIL_USE_SYSTEM_LOCK))
+/* Like malloc but get fatal error if memory is exhausted.  */
+
+static void *
+xmalloc (size_t size)
+{
+  void *result = malloc (size);
+  if (!result)
+    fatal ("virtual memory exhausted", 0, 0);
+  return result;
+}
+#endif
+
 /* Nonzero means this is name of a lock file to delete on fatal error.  */
 static char *delete_lockname;
 
@@ -169,7 +173,7 @@ main (int argc, char **argv)
   int tem;
   char *lockname;
   char *tempname;
-  size_t inname_dirlen;
+  size_t inname_len, inname_dirlen;
   int desc;
 #endif /* not MAIL_USE_SYSTEM_LOCK */
 
@@ -267,13 +271,6 @@ main (int argc, char **argv)
   else
 #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
@@ -282,23 +279,19 @@ main (int argc, char **argv)
         On systems that use a lock file, extracting the mail without locking
         WILL occasionally cause loss of mail due to timing errors!
 
-        So, if creation of the lock file fails
-        due to access permission on the mail spool directory,
-        you simply MUST change the permission
-        and/or make movemail a setgid program
+        So, if creation of the lock file fails due to access
+        permission on the mail spool directory, you simply MUST
+        change the permission and/or make movemail a setgid program
         so it can create lock files properly.
 
-        You might also wish to verify that your system is one
-        which uses lock files for this purpose.  Some systems use other methods.
-
-        If your system uses the `flock' system call for mail locking,
-        define MAIL_USE_SYSTEM_LOCK in config.h or the s-*.h file
-        and recompile movemail.  If the s- file for your system
-        should define MAIL_USE_SYSTEM_LOCK but does not, send a bug report
-        to bug-gnu-emacs@prep.ai.mit.edu so we can fix it.  */
+        You might also wish to verify that your system is one which
+        uses lock files for this purpose.  Some systems use other methods.  */
 
-      lockname = concat (inname, ".lock", "");
-      for (inname_dirlen = strlen (inname);
+      inname_len = strlen (inname);
+      lockname = xmalloc (inname_len + sizeof ".lock");
+      strcpy (lockname, inname);
+      strcpy (lockname + inname_len, ".lock");
+      for (inname_dirlen = inname_len;
           inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]);
           inname_dirlen--)
        continue;
@@ -335,11 +328,8 @@ main (int argc, char **argv)
 
          tem = link (tempname, lockname);
 
-#ifdef EPERM
-         if (tem < 0 && errno == EPERM)
-           fatal ("Unable to create hard link between %s and %s",
-                  tempname, lockname);
-#endif
+         if (tem < 0 && errno != EEXIST)
+           pfatal_with_name (lockname);
 
          unlink (tempname);
          if (tem >= 0)
@@ -390,13 +380,9 @@ main (int argc, char **argv)
       if (indesc < 0)
        pfatal_with_name (inname);
 
-#ifdef BSD_SYSTEM
-      /* In case movemail is setuid to root, make sure the user can
-        read the output file.  */
-      /* This is desirable for all systems
-        but I don't want to assume all have the umask system call */
-      umask (umask (0) & 0333);
-#endif /* BSD_SYSTEM */
+      /* Make sure the user can read the output file.  */
+      umask (umask (0) & 0377);
+
       outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666);
       if (outdesc < 0)
        pfatal_with_name (outname);
@@ -440,22 +426,10 @@ main (int argc, char **argv)
         for certain failure codes.  */
       if (status < 0)
        {
-         if (++lockcount <= 5)
+         if (++lockcount <= 5 && (errno == EAGAIN || errno == EBUSY))
            {
-#ifdef EAGAIN
-             if (errno == EAGAIN)
-               {
-                 sleep (1);
-                 goto retry_lock;
-               }
-#endif
-#ifdef EBUSY
-             if (errno == EBUSY)
-               {
-                 sleep (1);
-                 goto retry_lock;
-               }
-#endif
+             sleep (1);
+             goto retry_lock;
            }
 
          pfatal_with_name (inname);
@@ -492,10 +466,8 @@ main (int argc, char **argv)
          }
       }
 
-#ifdef BSD_SYSTEM
-      if (fsync (outdesc) < 0)
+      if (fsync (outdesc) != 0 && errno != EINVAL)
        pfatal_and_delete (outname);
-#endif
 
       /* Prevent symlink attacks truncating other users' mailboxes */
       if (setregid (-1, real_gid) < 0)
@@ -549,8 +521,8 @@ main (int argc, char **argv)
   wait (&wait_status);
   if (!WIFEXITED (wait_status))
     exit (EXIT_FAILURE);
-  else if (WRETCODE (wait_status) != 0)
-    exit (WRETCODE (wait_status));
+  else if (WEXITSTATUS (wait_status) != 0)
+    exit (WEXITSTATUS (wait_status));
 
 #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK)
 #ifdef MAIL_USE_MAILLOCK
@@ -644,19 +616,6 @@ pfatal_and_delete (char *name)
   unlink (name);
   fatal ("%s for %s", s, name);
 }
-
-#ifdef MAIL_USE_MAILLOCK
-/* Like malloc but get fatal error if memory is exhausted.  */
-
-static void *
-xmalloc (size_t size)
-{
-  void *result = malloc (size);
-  if (!result)
-    fatal ("virtual memory exhausted", 0, 0);
-  return result;
-}
-#endif
 \f
 /* This is the guts of the interface to the Post Office Protocol.  */
 
@@ -700,7 +659,6 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse
   register int i;
   int mbfi;
   FILE *mbf;
-  char *getenv (const char *);
   popserver server;
   int start, end, increment;
   char *user, *hostname;
@@ -790,21 +748,14 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse
        }
     }
 
-  /* On AFS, a call to write only modifies the file in the local
-   *     workstation's AFS cache.  The changes are not written to the server
-   *      until a call to fsync or close is made.  Users with AFS home
-   *      directories have lost mail when over quota because these checks were
-   *      not made in previous versions of movemail. */
-
-#ifdef BSD_SYSTEM
-  if (fsync (mbfi) < 0)
+  if (fsync (mbfi) != 0 && errno != EINVAL)
     {
       error ("Error in fsync: %s", strerror (errno), 0);
+      close (mbfi);
       return EXIT_FAILURE;
     }
-#endif
 
-  if (close (mbfi) == -1)
+  if (close (mbfi) != 0)
     {
       error ("Error in close: %s", strerror (errno), 0);
       return EXIT_FAILURE;
@@ -920,21 +871,3 @@ mbx_delimit_end (FILE *mbf)
 }
 
 #endif /* MAIL_USE_POP */
-\f
-#ifndef HAVE_STRERROR
-char *
-strerror (errnum)
-     int errnum;
-{
-  extern char *sys_errlist[];
-  extern int sys_nerr;
-
-  if (errnum >= 0 && errnum < sys_nerr)
-    return sys_errlist[errnum];
-  return (char *) "Unknown error";
-}
-
-#endif /* ! HAVE_STRERROR */
-
-
-/* movemail.c ends here */