Mercurial > emacs
changeset 16897:523d5c54a3f5
Include maillock.h (conditionally).
Remove a redundant inclusion of <stdio.h>.
(MAIL_USE_MAILLOCK): New macro, conditionally defined.
(main): Add variable spool_name.
Support the usage of maillock and mailunlock to
lock and unlock mailboxes.
(mail_spool_name): New function.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 20 Jan 1997 07:30:40 +0000 |
parents | b2c51d6de440 |
children | 6370d4132d69 |
files | lib-src/movemail.c |
diffstat | 1 files changed, 167 insertions(+), 68 deletions(-) [+] |
line wrap: on
line diff
--- a/lib-src/movemail.c Mon Jan 20 02:22:25 1997 +0000 +++ b/lib-src/movemail.c Mon Jan 20 07:30:40 1997 +0000 @@ -121,6 +121,17 @@ extern int lk_open (), lk_close (); #endif +#if !defined (MAIL_USE_SYSTEM_LOCK) && !defined (MAIL_USE_MMDF) && \ + defined (HAVE_LIBMAIL) && defined (HAVE_MAILLOCK_H) +#include <maillock.h> +/* We can't use maillock unless we know what directory system mail + files appear in. */ +#ifdef MAILDIR +#define MAIL_USE_MAILLOCK +static char *mail_spool_name (); +#endif +#endif + /* Cancel substitutions made by config.h for Emacs. */ #undef open #undef read @@ -166,12 +177,16 @@ int desc; #endif /* not MAIL_USE_SYSTEM_LOCK */ +#ifdef MAIL_USE_MAILLOCK + char *spool_name; +#endif + delete_lockname = 0; if (argc < 3) { fprintf (stderr, "Usage: movemail inbox destfile [POP-password]\n"); - exit(1); + exit (1); } inname = argv[1]; @@ -223,80 +238,89 @@ #ifndef MAIL_USE_MMDF #ifndef MAIL_USE_SYSTEM_LOCK - /* 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 - (on systems which use it) to prevent loss of mail. - - On systems that use a lock file, extracting the mail without locking - WILL occasionally cause loss of mail due to timing errors! +#ifdef MAIL_USE_MAILLOCK + spool_name = mail_spool_name (inname); + if (! spool_name) +#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 + (on systems which use it) to prevent loss of mail. - 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. + On systems that use a lock file, extracting the mail without locking + WILL occasionally cause loss of mail due to timing errors! - 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. */ + 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. - 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. + + 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. */ - 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); - if (desc < 0) - { - char *message = (char *) xmalloc (strlen (tempname) + 50); - sprintf (message, "%s--see source file lib-src/movemail.c", - tempname); - pfatal_with_name (message); - } - close (desc); - - tem = link (tempname, lockname); + 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); - if (tem >= 0) - break; - sleep (1); + + 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); + if (desc < 0) + { + char *message = (char *) xmalloc (strlen (tempname) + 50); + sprintf (message, "%s--see source file lib-src/movemail.c", + tempname); + pfatal_with_name (message); + } + close (desc); - /* If lock file is five minutes old, unlock it. - Five minutes should be good enough to cope with crashes - and wedgitude, and long enough to avoid being fooled - by time differences between machines. */ - if (stat (lockname, &st) >= 0) - { - now = time (0); - if (st.st_ctime < now - 300) - unlink (lockname); + tem = link (tempname, lockname); + unlink (tempname); + if (tem >= 0) + break; + sleep (1); + + /* If lock file is five minutes old, unlock it. + Five minutes should be good enough to cope with crashes + and wedgitude, and long enough to avoid being fooled + by time differences between machines. */ + if (stat (lockname, &st) >= 0) + { + now = time (0); + if (st.st_ctime < now - 300) + unlink (lockname); + } } + + delete_lockname = lockname; } - - delete_lockname = lockname; #endif /* not MAIL_USE_SYSTEM_LOCK */ #endif /* not MAIL_USE_MMDF */ if (fork () == 0) { int lockcount = 0; - int status; + int status = 0; +#if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) + long touched_lock, now; +#endif setuid (getuid ()); @@ -329,21 +353,36 @@ retry_lock: /* Try to lock it. */ +#ifdef MAIL_USE_MAILLOCK + if (spool_name) + { + /* The "0 - " is to make it a negative number if maillock returns + non-zero. */ + status = 0 - maillock (spool_name, 1); +#ifdef HAVE_TOUCHLOCK + touched_lock = time (0); +#endif + lockcount = 5; + } + else +#endif /* MAIL_USE_MAILLOCK */ + { #ifdef MAIL_USE_SYSTEM_LOCK #ifdef MAIL_USE_LOCKF - status = lockf (indesc, F_LOCK, 0); + status = lockf (indesc, F_LOCK, 0); #else /* not MAIL_USE_LOCKF */ #ifdef XENIX - status = locking (indesc, LK_RLCK, 0L); + status = locking (indesc, LK_RLCK, 0L); #else #ifdef WINDOWSNT - status = locking (indesc, LK_RLCK, -1L); + status = locking (indesc, LK_RLCK, -1L); #else - status = flock (indesc, LOCK_EX); + status = flock (indesc, LOCK_EX); #endif #endif #endif /* not MAIL_USE_LOCKF */ #endif /* MAIL_USE_SYSTEM_LOCK */ + } /* If it fails, retry up to 5 times for certain failure codes. */ @@ -385,6 +424,17 @@ } if (nread < sizeof buf) break; +#if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) + if (spool_name) + { + now = time (0); + if (now - touched_lock > 60) + { + touchlock (); + touched_lock = now; + } + } +#endif /* MAIL_USE_MAILLOCK */ } } @@ -423,6 +473,12 @@ creat (inname, 0600); #endif /* not MAIL_USE_SYSTEM_LOCK */ +#ifdef MAIL_USE_MAILLOCK + /* This has to occur in the child, i.e., in the process that + acquired the lock! */ + if (spool_name) + mailunlock (); +#endif exit (0); } @@ -433,13 +489,57 @@ exit (WRETCODE (status)); #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) - unlink (lockname); +#ifdef MAIL_USE_MAILLOCK + if (! spool_name) +#endif /* MAIL_USE_MAILLOCK */ + unlink (lockname); #endif /* not MAIL_USE_MMDF and not MAIL_USE_SYSTEM_LOCK */ #endif /* ! DISABLE_DIRECT_ACCESS */ return 0; } + +#ifdef MAIL_USE_MAILLOCK +/* This function uses stat to confirm that the mail directory is + identical to the directory of the input file, rather than just + 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; +{ + struct stat stat1, stat2; + char *indir, *fname; + int status; + + if (! (fname = rindex (inname, '/'))) + return NULL; + + fname++; + + if (stat (MAILDIR, &stat1) < 0) + return NULL; + + indir = (char *) xmalloc (fname - inname + 1); + strncpy (indir, inname, fname - inname); + indir[fname-inname] = '\0'; + + + status = stat (indir, &stat2); + + free (indir); + + if (status < 0) + return NULL; + + if ((stat1.st_dev == stat2.st_dev) && + (stat1.st_ino == stat2.st_ino)) + return fname; + + return NULL; +} +#endif /* MAIL_USE_MAILLOCK */ /* Print error message and exit. */ @@ -522,7 +622,6 @@ #undef _WINSOCKAPI_ #include <winsock.h> #endif -#include <stdio.h> #include <pwd.h> #ifdef USG @@ -657,7 +756,7 @@ pop_retr (server, msgno, action, arg) popserver server; - int (*action)(); + int (*action) (); { extern char *strerror (); char *line;