X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/4822b2e57fd58d2d7c26a89f25009dd9b21a6f11..03da5d089a8ed035cec443a27259e7d21487a22e:/lib-src/movemail.c diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 1ab59c0e5d..e8f1122e94 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c @@ -1,6 +1,7 @@ /* movemail foo bar -- move file foo to file bar, locking file foo the way /bin/mail respects. - Copyright (C) 1986, 1992, 1993, 1994, 1996 Free Software Foundation, Inc. + Copyright (C) 1986, 1992, 1993, 1994, 1996, 1999, 2002, 2003, 2004, + 2005 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -16,8 +17,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301, USA. */ /* 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 @@ -39,11 +40,11 @@ Boston, MA 02111-1307, USA. */ * "po:username". This will cause movemail to open a connection to * a pop server running on $MAILHOST (environment variable). Movemail * must be setuid to root in order to work with POP. - * + * * New module: popmail.c * Modified routines: * main - added code within #ifdef MAIL_USE_POP; added setuid (getuid ()) - * after POP code. + * after POP code. * New routines in movemail.c: * get_errmsg - return pointer to system error message * @@ -55,14 +56,21 @@ Boston, MA 02111-1307, USA. */ */ #define NO_SHORTNAMES /* Tell config not to load remap.h */ -#include <../src/config.h> +#include #include #include #include #include #include -#include <../src/syswait.h> + #include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#include "syswait.h" #ifdef MAIL_USE_POP #include "pop.h" #endif @@ -95,35 +103,15 @@ Boston, MA 02111-1307, USA. */ implemented and used on Unix. */ //#define DISABLE_DIRECT_ACCESS -/* Ensure all file i/o is in binary mode. */ #include -int _fmode = _O_BINARY; #endif /* WINDOWSNT */ -/* Cancel substitutions made by config.h for Emacs. */ -#undef open -#undef read -#undef write -#undef close - -#ifdef USG -#include -#include #ifndef F_OK #define F_OK 0 #define X_OK 1 #define W_OK 2 #define R_OK 4 #endif -#endif /* USG */ - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef STDC_HEADERS -#include -#endif #if defined (XENIX) || defined (WINDOWSNT) #include @@ -142,7 +130,8 @@ extern int lk_open (), lk_close (); #endif #if !defined (MAIL_USE_SYSTEM_LOCK) && !defined (MAIL_USE_MMDF) && \ - defined (HAVE_LIBMAIL) && defined (HAVE_MAILLOCK_H) + (defined (HAVE_LIBMAIL) || defined (HAVE_LIBLOCKFILE)) && \ + defined (HAVE_MAILLOCK_H) #include /* We can't use maillock unless we know what directory system mail files appear in. */ @@ -156,7 +145,12 @@ static char *mail_spool_name (); extern int errno; #endif char *strerror (); -extern char *rindex (); +#ifdef HAVE_INDEX +extern char *index __P ((const char *, int)); +#endif +#ifdef HAVE_RINDEX +extern char *rindex __P((const char *, int)); +#endif void fatal (); void error (); @@ -197,16 +191,33 @@ main (argc, argv) char *spool_name; #endif +#ifdef MAIL_USE_POP + int pop_reverse_order = 0; +# define ARGSTR "pr" +#else /* ! MAIL_USE_POP */ +# define ARGSTR "p" +#endif /* MAIL_USE_POP */ + +#ifdef WINDOWSNT + /* Ensure all file i/o is in binary mode. */ + _fmode = _O_BINARY; +#endif + delete_lockname = 0; - while ((c = getopt (argc, argv, "p")) != EOF) + while ((c = getopt (argc, argv, ARGSTR)) != EOF) { switch (c) { +#ifdef MAIL_USE_POP + case 'r': + pop_reverse_order = 1; + break; +#endif case 'p': preserve_mail++; break; default: - exit(1); + exit (EXIT_FAILURE); } } @@ -218,14 +229,13 @@ main (argc, argv) #endif ) { - fprintf (stderr, "Usage: movemail [-p] inbox destfile%s\n", #ifdef MAIL_USE_POP - " [POP-password]" + fprintf (stderr, "Usage: movemail [-p] inbox destfile%s\n", + " [POP-password]"); #else - "" + fprintf (stderr, "Usage: movemail [-p] inbox destfile%s\n", ""); #endif - ); - exit (1); + exit (EXIT_FAILURE); } inname = argv[optind]; @@ -236,7 +246,7 @@ main (argc, argv) #endif if (*outname == 0) - fatal ("Destination file name is empty", 0); + fatal ("Destination file name is empty", 0, 0); /* Check access to output file. */ if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0) @@ -263,7 +273,8 @@ main (argc, argv) int status; status = popmail (inname + 3, outname, preserve_mail, - (argc - optind == 3) ? argv[optind+2] : NULL); + (argc - optind == 3) ? argv[optind+2] : NULL, + pop_reverse_order); exit (status); } @@ -325,7 +336,7 @@ main (argc, argv) if (desc < 0) { char *message = (char *) xmalloc (strlen (tempname) + 50); - sprintf (message, "%s--see source file lib-src/movemail.c", + sprintf (message, "creating %s, which would become the lock file", tempname); pfatal_with_name (message); } @@ -448,7 +459,7 @@ main (argc, argv) pfatal_with_name (inname); } - + { char buf[1024]; @@ -490,7 +501,7 @@ main (argc, argv) #ifdef MAIL_USE_SYSTEM_LOCK if (! preserve_mail) { -#if defined (STRIDE) || defined (XENIX) || defined (WINDOWSNT) +#if defined (STRIDE) || defined (XENIX) /* Stride, xenix have file locking, but no ftruncate. This mess will do. */ close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666)); @@ -526,12 +537,12 @@ main (argc, argv) if (spool_name) mailunlock (); #endif - exit (0); + exit (EXIT_SUCCESS); } wait (&status); if (!WIFEXITED (status)) - exit (1); + exit (EXIT_FAILURE); else if (WRETCODE (status) != 0) exit (WRETCODE (status)); @@ -544,7 +555,7 @@ main (argc, argv) #endif /* ! DISABLE_DIRECT_ACCESS */ - return 0; + return EXIT_SUCCESS; } #ifdef MAIL_USE_MAILLOCK @@ -591,23 +602,29 @@ mail_spool_name (inname) /* Print error message and exit. */ void -fatal (s1, s2) - char *s1, *s2; +fatal (s1, s2, s3) + char *s1, *s2, *s3; { if (delete_lockname) unlink (delete_lockname); - error (s1, s2); - exit (1); + error (s1, s2, s3); + exit (EXIT_FAILURE); } -/* Print error message. `s1' is printf control string, `s2' is arg for it. */ +/* Print error message. `s1' is printf control string, `s2' and `s3' + are args for it or null. */ void error (s1, s2, s3) char *s1, *s2, *s3; { fprintf (stderr, "movemail: "); - fprintf (stderr, s1, s2, s3); + if (s3) + fprintf (stderr, s1, s2, s3); + else if (s2) + fprintf (stderr, s1, s2); + else + fprintf (stderr, s1); fprintf (stderr, "\n"); } @@ -615,17 +632,16 @@ void pfatal_with_name (name) char *name; { - char *s = concat ("", strerror (errno), " for %s"); - fatal (s, name); + fatal ("%s for %s", strerror (errno), name); } void pfatal_and_delete (name) char *name; { - char *s = concat ("", strerror (errno), " for %s"); + char *s = strerror (errno); unlink (name); - fatal (s, name); + fatal ("%s for %s", s, name); } /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ @@ -653,7 +669,7 @@ xmalloc (size) { long *result = (long *) malloc (size); if (!result) - fatal ("virtual memory exhausted", 0); + fatal ("virtual memory exhausted", 0, 0); return result; } @@ -680,13 +696,30 @@ FILE *sfi; FILE *sfo; char ibuffer[BUFSIZ]; char obuffer[BUFSIZ]; -char Errmsg[80]; +char Errmsg[200]; /* POP errors, at least, can exceed + the original length of 80. */ + +/* + * The full legal syntax for a POP mailbox specification for movemail + * is "po:username:hostname". The ":hostname" is optional; if it is + * omitted, the MAILHOST environment variable will be consulted. Note + * that by the time popmail() is called the "po:" has been stripped + * off of the front of the mailbox name. + * + * If the mailbox is in the form "po:username:hostname", then it is + * modified by this function -- the second colon is replaced by a + * null. + * + * Return a value suitable for passing to `exit'. + */ -popmail (user, outfile, preserve, password) - char *user; +int +popmail (mailbox, outfile, preserve, password, reverse_order) + char *mailbox; char *outfile; int preserve; char *password; + int reverse_order; { int nmsgs, nbytes; register int i; @@ -694,24 +727,30 @@ popmail (user, outfile, preserve, password) FILE *mbf; char *getenv (); popserver server; + int start, end, increment; + char *user, *hostname; + + user = mailbox; + if ((hostname = index(mailbox, ':'))) + *hostname++ = '\0'; - server = pop_open (0, user, password, POP_NO_GETPASS); + server = pop_open (hostname, user, password, POP_NO_GETPASS); if (! server) { - error (pop_error); - return (1); + error ("Error connecting to POP server: %s", pop_error, 0); + return EXIT_FAILURE; } if (pop_stat (server, &nmsgs, &nbytes)) { - error (pop_error); - return (1); + error ("Error getting message count from POP server: %s", pop_error, 0); + return EXIT_FAILURE; } if (!nmsgs) { pop_close (server); - return (0); + return EXIT_SUCCESS; } mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); @@ -719,36 +758,49 @@ popmail (user, outfile, preserve, password) { pop_close (server); error ("Error in open: %s, %s", strerror (errno), outfile); - return (1); + return EXIT_FAILURE; } fchown (mbfi, getuid (), -1); if ((mbf = fdopen (mbfi, "wb")) == NULL) { pop_close (server); - error ("Error in fdopen: %s", strerror (errno)); + error ("Error in fdopen: %s", strerror (errno), 0); close (mbfi); unlink (outfile); - return (1); + return EXIT_FAILURE; } - for (i = 1; i <= nmsgs; i++) + if (reverse_order) + { + start = nmsgs; + end = 1; + increment = -1; + } + else + { + start = 1; + end = nmsgs; + increment = 1; + } + + for (i = start; i * increment <= end * increment; i += increment) { mbx_delimit_begin (mbf); if (pop_retr (server, i, mbf) != OK) { - error (Errmsg); + error ("%s", Errmsg, 0); close (mbfi); - return (1); + return EXIT_FAILURE; } mbx_delimit_end (mbf); fflush (mbf); if (ferror (mbf)) { - error ("Error in fflush: %s", strerror (errno)); + error ("Error in fflush: %s", strerror (errno), 0); pop_close (server); close (mbfi); - return (1); + return EXIT_FAILURE; } } @@ -761,15 +813,15 @@ popmail (user, outfile, preserve, password) #ifdef BSD_SYSTEM if (fsync (mbfi) < 0) { - error ("Error in fsync: %s", strerror (errno)); - return (1); + error ("Error in fsync: %s", strerror (errno), 0); + return EXIT_FAILURE; } #endif if (close (mbfi) == -1) { - error ("Error in close: %s", strerror (errno)); - return (1); + error ("Error in close: %s", strerror (errno), 0); + return EXIT_FAILURE; } if (! preserve) @@ -777,24 +829,25 @@ popmail (user, outfile, preserve, password) { if (pop_delete (server, i)) { - error (pop_error); + error ("Error from POP server: %s", pop_error, 0); pop_close (server); - return (1); + return EXIT_FAILURE; } } if (pop_quit (server)) { - error (pop_error); - return (1); + error ("Error from POP server: %s", pop_error, 0); + return EXIT_FAILURE; } - - return (0); + + return EXIT_SUCCESS; } int pop_retr (server, msgno, arg) popserver server; + int msgno; FILE *arg; { extern char *strerror (); @@ -803,8 +856,10 @@ pop_retr (server, msgno, arg) if (pop_retrieve_first (server, msgno, &line)) { - strncpy (Errmsg, pop_error, sizeof (Errmsg)); + char *error = concat ("Error from POP server: ", pop_error, ""); + strncpy (Errmsg, error, sizeof (Errmsg)); Errmsg[sizeof (Errmsg)-1] = '\0'; + free(error); return (NOTOK); } @@ -823,8 +878,10 @@ pop_retr (server, msgno, arg) if (ret) { - strncpy (Errmsg, pop_error, sizeof (Errmsg)); + char *error = concat ("Error from POP server: ", pop_error, ""); + strncpy (Errmsg, error, sizeof (Errmsg)); Errmsg[sizeof (Errmsg)-1] = '\0'; + free(error); return (NOTOK); } @@ -858,7 +915,7 @@ mbx_write (line, len, mbf) line++; len--; } - if (fwrite (line, 1, len, mbf) != len) + if (fwrite (line, 1, len, mbf) != len) return (NOTOK); if (fputc (0x0a, mbf) == EOF) return (NOTOK); @@ -874,6 +931,7 @@ mbx_delimit_begin (mbf) return (OK); } +int mbx_delimit_end (mbf) FILE *mbf; { @@ -898,3 +956,8 @@ strerror (errnum) } #endif /* ! HAVE_STRERROR */ + +/* arch-tag: 1c323112-41fe-4fe5-8de9-494de631f73f + (do not change this comment) */ + +/* movemail.c ends here */