X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/09d9db2c4921cb2eb0974892164dd03d6bffdd80..2e8efb2f47b90edd393bde33bf048333b3bde279:/lib-src/movemail.c diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 4a894c1cba..32d32e69ab 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -1,7 +1,7 @@ /* 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-2011 +Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -22,7 +22,7 @@ along with GNU Emacs. If not, see . */ /* 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. @@ -68,9 +68,7 @@ along with GNU Emacs. If not, see . */ #ifdef HAVE_FCNTL_H #include #endif -#ifdef HAVE_STRING_H #include -#endif #include "syswait.h" #ifdef MAIL_USE_POP #include "pop.h" @@ -111,6 +109,11 @@ along with GNU Emacs. If not, see . */ #include #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 @@ -131,20 +134,14 @@ extern int lk_open (), lk_close (); files appear in. */ #ifdef MAILDIR #define MAIL_USE_MAILLOCK -static char *mail_spool_name (); -#endif +static char *mail_spool_name (char *); #endif - -#ifndef HAVE_STRERROR -char *strerror (int); #endif -static void fatal (const char *s1, const char *s2, const char *s3) NO_RETURN; +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 void pfatal_with_name (char *name) NO_RETURN; -static void pfatal_and_delete (char *name) NO_RETURN; -static char *concat (const char *s1, const char *s2, const char *s3); -static long *xmalloc (unsigned int size); +static _Noreturn void pfatal_with_name (char *name); +static _Noreturn void pfatal_and_delete (char *name); #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); @@ -153,6 +150,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; @@ -167,10 +179,10 @@ main (int argc, char **argv) #ifndef MAIL_USE_SYSTEM_LOCK struct stat st; - long now; int tem; - char *lockname, *p; + char *lockname; char *tempname; + size_t inname_len, inname_dirlen; int desc; #endif /* not MAIL_USE_SYSTEM_LOCK */ @@ -185,8 +197,8 @@ main (int argc, char **argv) # define ARGSTR "p" #endif /* MAIL_USE_POP */ - uid_t real_gid = getgid(); - uid_t priv_gid = getegid(); + uid_t real_gid = getgid (); + uid_t priv_gid = getegid (); #ifdef WINDOWSNT /* Ensure all file i/o is in binary mode. */ @@ -259,16 +271,15 @@ main (int argc, char **argv) #ifndef MAIL_USE_SYSTEM_LOCK #ifdef MAIL_USE_MAILLOCK spool_name = mail_spool_name (inname); - if (! spool_name) + if (spool_name) + { +#ifdef lint + lockname = 0; +#endif + } + 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 @@ -277,43 +288,50 @@ 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. */ - - lockname = concat (inname, ".lock", ""); - tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); - strcpy (tempname, inname); - p = tempname + strlen (tempname); - while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) - p--; - *p = 0; - strcpy (p, "EXXXXXX"); - mktemp (tempname); - unlink (tempname); + You might also wish to verify that your system is one which + uses lock files for this purpose. Some systems use other methods. */ + + 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; + tempname = xmalloc (inname_dirlen + sizeof "EXXXXXX"); while (1) { /* Create the lock file, but not under the lock file name. */ /* Give up if cannot do that. */ - desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666); + + memcpy (tempname, inname, inname_dirlen); + strcpy (tempname + inname_dirlen, "EXXXXXX"); +#ifdef HAVE_MKSTEMP + desc = mkstemp (tempname); +#else + mktemp (tempname); + if (!*tempname) + desc = -1; + else + { + unlink (tempname); + desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600); + } +#endif if (desc < 0) { - char *message = (char *) xmalloc (strlen (tempname) + 50); - sprintf (message, "creating %s, which would become the lock file", - tempname); - pfatal_with_name (message); + int mkstemp_errno = errno; + error ("error while creating what would become the lock file", + 0, 0); + errno = mkstemp_errno; + pfatal_with_name (tempname); } close (desc); @@ -336,7 +354,7 @@ main (int argc, char **argv) by time differences between machines. */ if (stat (lockname, &st) >= 0) { - now = time (0); + time_t now = time (0); if (st.st_ctime < now - 300) unlink (lockname); } @@ -352,7 +370,10 @@ main (int argc, char **argv) int lockcount = 0; int status = 0; #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) - time_t touched_lock, now; + time_t touched_lock; +# ifdef lint + touched_lock = 0; +# endif #endif if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0) @@ -462,7 +483,7 @@ main (int argc, char **argv) #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) if (spool_name) { - now = time (0); + time_t now = time (0); if (now - touched_lock > 60) { touchlock (); @@ -530,8 +551,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 @@ -565,8 +586,8 @@ mail_spool_name (char *inname) if (stat (MAILDIR, &stat1) < 0) return NULL; - indir = (char *) xmalloc (fname - inname + 1); - strncpy (indir, inname, fname - inname); + indir = xmalloc (fname - inname + 1); + memcpy (indir, inname, fname - inname); indir[fname-inname] = '\0'; @@ -625,33 +646,6 @@ pfatal_and_delete (char *name) unlink (name); fatal ("%s for %s", s, name); } - -/* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ - -static char * -concat (const char *s1, const char *s2, const char *s3) -{ - size_t len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); - char *result = (char *) xmalloc (len1 + len2 + len3 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - strcpy (result + len1 + len2, s3); - *(result + len1 + len2 + len3) = 0; - - return result; -} - -/* Like malloc but get fatal error if memory is exhausted. */ - -static long * -xmalloc (unsigned int size) -{ - long *result = (long *) malloc (size); - if (!result) - fatal ("virtual memory exhausted", 0, 0); - return result; -} /* This is the guts of the interface to the Post Office Protocol. */ @@ -833,10 +827,7 @@ pop_retr (popserver server, int msgno, FILE *arg) if (pop_retrieve_first (server, msgno, &line)) { - char *msg = concat ("Error from POP server: ", pop_error, ""); - strncpy (Errmsg, msg, sizeof (Errmsg)); - Errmsg[sizeof (Errmsg)-1] = '\0'; - free (msg); + snprintf (Errmsg, sizeof Errmsg, "Error from POP server: %s", pop_error); return (NOTOK); } @@ -855,10 +846,7 @@ pop_retr (popserver server, int msgno, FILE *arg) if (ret) { - char *msg = concat ("Error from POP server: ", pop_error, ""); - strncpy (Errmsg, msg, sizeof (Errmsg)); - Errmsg[sizeof (Errmsg)-1] = '\0'; - free (msg); + snprintf (Errmsg, sizeof Errmsg, "Error from POP server: %s", pop_error); return (NOTOK); } @@ -921,21 +909,3 @@ mbx_delimit_end (FILE *mbf) } #endif /* MAIL_USE_POP */ - -#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 */