diff options
Diffstat (limited to 'lib-src/movemail.c')
| -rw-r--r-- | lib-src/movemail.c | 150 |
1 files changed, 45 insertions, 105 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c index b6ea51f6341..264b3d292c6 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* movemail foo bar -- move file foo to file bar, | 1 | /* movemail foo bar -- move file foo to file bar, |
| 2 | locking file foo the way /bin/mail respects. | 2 | locking file foo the way /bin/mail respects. |
| 3 | 3 | ||
| 4 | Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2011 | 4 | Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2012 |
| 5 | Free Software Foundation, Inc. | 5 | Free Software Foundation, Inc. |
| 6 | 6 | ||
| 7 | This file is part of GNU Emacs. | 7 | This file is part of GNU Emacs. |
| @@ -22,7 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 22 | 22 | ||
| 23 | /* Important notice: defining MAIL_USE_FLOCK or MAIL_USE_LOCKF *will | 23 | /* Important notice: defining MAIL_USE_FLOCK or MAIL_USE_LOCKF *will |
| 24 | cause loss of mail* if you do it on a system that does not normally | 24 | cause loss of mail* if you do it on a system that does not normally |
| 25 | use flock as its way of interlocking access to inbox files. The | 25 | use flock/lockf as its way of interlocking access to inbox files. The |
| 26 | setting of MAIL_USE_FLOCK and MAIL_USE_LOCKF *must agree* with the | 26 | setting of MAIL_USE_FLOCK and MAIL_USE_LOCKF *must agree* with the |
| 27 | system's own conventions. It is not a choice that is up to you. | 27 | system's own conventions. It is not a choice that is up to you. |
| 28 | 28 | ||
| @@ -65,9 +65,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 65 | 65 | ||
| 66 | #include <getopt.h> | 66 | #include <getopt.h> |
| 67 | #include <unistd.h> | 67 | #include <unistd.h> |
| 68 | #ifdef HAVE_FCNTL_H | ||
| 69 | #include <fcntl.h> | 68 | #include <fcntl.h> |
| 70 | #endif | ||
| 71 | #include <string.h> | 69 | #include <string.h> |
| 72 | #include "syswait.h" | 70 | #include "syswait.h" |
| 73 | #ifdef MAIL_USE_POP | 71 | #ifdef MAIL_USE_POP |
| @@ -98,17 +96,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 98 | #include <fcntl.h> | 96 | #include <fcntl.h> |
| 99 | #endif /* WINDOWSNT */ | 97 | #endif /* WINDOWSNT */ |
| 100 | 98 | ||
| 101 | #ifndef F_OK | ||
| 102 | #define F_OK 0 | ||
| 103 | #define X_OK 1 | ||
| 104 | #define W_OK 2 | ||
| 105 | #define R_OK 4 | ||
| 106 | #endif | ||
| 107 | |||
| 108 | #ifdef WINDOWSNT | 99 | #ifdef WINDOWSNT |
| 109 | #include <sys/locking.h> | 100 | #include <sys/locking.h> |
| 110 | #endif | 101 | #endif |
| 111 | 102 | ||
| 103 | /* If your system uses the `flock' or `lockf' system call for mail locking, | ||
| 104 | define MAIL_USE_SYSTEM_LOCK. If your system type should always define | ||
| 105 | MAIL_USE_LOCKF or MAIL_USE_FLOCK but configure does not do this, | ||
| 106 | please make a bug report. */ | ||
| 107 | |||
| 112 | #ifdef MAIL_USE_LOCKF | 108 | #ifdef MAIL_USE_LOCKF |
| 113 | #define MAIL_USE_SYSTEM_LOCK | 109 | #define MAIL_USE_SYSTEM_LOCK |
| 114 | #endif | 110 | #endif |
| @@ -133,16 +129,10 @@ static char *mail_spool_name (char *); | |||
| 133 | #endif | 129 | #endif |
| 134 | #endif | 130 | #endif |
| 135 | 131 | ||
| 136 | #ifndef HAVE_STRERROR | 132 | static _Noreturn void fatal (const char *s1, const char *s2, const char *s3); |
| 137 | char *strerror (int); | ||
| 138 | #endif | ||
| 139 | |||
| 140 | static void fatal (const char *s1, const char *s2, const char *s3) NO_RETURN; | ||
| 141 | static void error (const char *s1, const char *s2, const char *s3); | 133 | static void error (const char *s1, const char *s2, const char *s3); |
| 142 | static void pfatal_with_name (char *name) NO_RETURN; | 134 | static _Noreturn void pfatal_with_name (char *name); |
| 143 | static void pfatal_and_delete (char *name) NO_RETURN; | 135 | static _Noreturn void pfatal_and_delete (char *name); |
| 144 | static char *concat (const char *s1, const char *s2, const char *s3); | ||
| 145 | static long *xmalloc (unsigned int size); | ||
| 146 | #ifdef MAIL_USE_POP | 136 | #ifdef MAIL_USE_POP |
| 147 | static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order); | 137 | static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order); |
| 148 | static int pop_retr (popserver server, int msgno, FILE *arg); | 138 | static int pop_retr (popserver server, int msgno, FILE *arg); |
| @@ -151,6 +141,21 @@ static int mbx_delimit_begin (FILE *mbf); | |||
| 151 | static int mbx_delimit_end (FILE *mbf); | 141 | static int mbx_delimit_end (FILE *mbf); |
| 152 | #endif | 142 | #endif |
| 153 | 143 | ||
| 144 | #if (defined MAIL_USE_MAILLOCK \ | ||
| 145 | || (!defined DISABLE_DIRECT_ACCESS && !defined MAIL_USE_MMDF \ | ||
| 146 | && !defined MAIL_USE_SYSTEM_LOCK)) | ||
| 147 | /* Like malloc but get fatal error if memory is exhausted. */ | ||
| 148 | |||
| 149 | static void * | ||
| 150 | xmalloc (size_t size) | ||
| 151 | { | ||
| 152 | void *result = malloc (size); | ||
| 153 | if (!result) | ||
| 154 | fatal ("virtual memory exhausted", 0, 0); | ||
| 155 | return result; | ||
| 156 | } | ||
| 157 | #endif | ||
| 158 | |||
| 154 | /* Nonzero means this is name of a lock file to delete on fatal error. */ | 159 | /* Nonzero means this is name of a lock file to delete on fatal error. */ |
| 155 | static char *delete_lockname; | 160 | static char *delete_lockname; |
| 156 | 161 | ||
| @@ -168,7 +173,7 @@ main (int argc, char **argv) | |||
| 168 | int tem; | 173 | int tem; |
| 169 | char *lockname; | 174 | char *lockname; |
| 170 | char *tempname; | 175 | char *tempname; |
| 171 | size_t inname_dirlen; | 176 | size_t inname_len, inname_dirlen; |
| 172 | int desc; | 177 | int desc; |
| 173 | #endif /* not MAIL_USE_SYSTEM_LOCK */ | 178 | #endif /* not MAIL_USE_SYSTEM_LOCK */ |
| 174 | 179 | ||
| @@ -266,13 +271,6 @@ main (int argc, char **argv) | |||
| 266 | else | 271 | else |
| 267 | #endif | 272 | #endif |
| 268 | { | 273 | { |
| 269 | #ifndef DIRECTORY_SEP | ||
| 270 | #define DIRECTORY_SEP '/' | ||
| 271 | #endif | ||
| 272 | #ifndef IS_DIRECTORY_SEP | ||
| 273 | #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) | ||
| 274 | #endif | ||
| 275 | |||
| 276 | /* Use a lock file named after our first argument with .lock appended: | 274 | /* Use a lock file named after our first argument with .lock appended: |
| 277 | If it exists, the mail file is locked. */ | 275 | If it exists, the mail file is locked. */ |
| 278 | /* Note: this locking mechanism is *required* by the mailer | 276 | /* Note: this locking mechanism is *required* by the mailer |
| @@ -281,27 +279,23 @@ main (int argc, char **argv) | |||
| 281 | On systems that use a lock file, extracting the mail without locking | 279 | On systems that use a lock file, extracting the mail without locking |
| 282 | WILL occasionally cause loss of mail due to timing errors! | 280 | WILL occasionally cause loss of mail due to timing errors! |
| 283 | 281 | ||
| 284 | So, if creation of the lock file fails | 282 | So, if creation of the lock file fails due to access |
| 285 | due to access permission on the mail spool directory, | 283 | permission on the mail spool directory, you simply MUST |
| 286 | you simply MUST change the permission | 284 | change the permission and/or make movemail a setgid program |
| 287 | and/or make movemail a setgid program | ||
| 288 | so it can create lock files properly. | 285 | so it can create lock files properly. |
| 289 | 286 | ||
| 290 | You might also wish to verify that your system is one | 287 | You might also wish to verify that your system is one which |
| 291 | which uses lock files for this purpose. Some systems use other methods. | 288 | uses lock files for this purpose. Some systems use other methods. */ |
| 292 | 289 | ||
| 293 | If your system uses the `flock' system call for mail locking, | 290 | inname_len = strlen (inname); |
| 294 | define MAIL_USE_SYSTEM_LOCK in config.h or the s-*.h file | 291 | lockname = xmalloc (inname_len + sizeof ".lock"); |
| 295 | and recompile movemail. If the s- file for your system | 292 | strcpy (lockname, inname); |
| 296 | should define MAIL_USE_SYSTEM_LOCK but does not, send a bug report | 293 | strcpy (lockname + inname_len, ".lock"); |
| 297 | to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ | 294 | for (inname_dirlen = inname_len; |
| 298 | |||
| 299 | lockname = concat (inname, ".lock", ""); | ||
| 300 | for (inname_dirlen = strlen (inname); | ||
| 301 | inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]); | 295 | inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]); |
| 302 | inname_dirlen--) | 296 | inname_dirlen--) |
| 303 | continue; | 297 | continue; |
| 304 | tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX"); | 298 | tempname = xmalloc (inname_dirlen + sizeof "EXXXXXX"); |
| 305 | 299 | ||
| 306 | while (1) | 300 | while (1) |
| 307 | { | 301 | { |
| @@ -334,11 +328,8 @@ main (int argc, char **argv) | |||
| 334 | 328 | ||
| 335 | tem = link (tempname, lockname); | 329 | tem = link (tempname, lockname); |
| 336 | 330 | ||
| 337 | #ifdef EPERM | 331 | if (tem < 0 && errno != EEXIST) |
| 338 | if (tem < 0 && errno == EPERM) | 332 | pfatal_with_name (lockname); |
| 339 | fatal ("Unable to create hard link between %s and %s", | ||
| 340 | tempname, lockname); | ||
| 341 | #endif | ||
| 342 | 333 | ||
| 343 | unlink (tempname); | 334 | unlink (tempname); |
| 344 | if (tem >= 0) | 335 | if (tem >= 0) |
| @@ -548,8 +539,8 @@ main (int argc, char **argv) | |||
| 548 | wait (&wait_status); | 539 | wait (&wait_status); |
| 549 | if (!WIFEXITED (wait_status)) | 540 | if (!WIFEXITED (wait_status)) |
| 550 | exit (EXIT_FAILURE); | 541 | exit (EXIT_FAILURE); |
| 551 | else if (WRETCODE (wait_status) != 0) | 542 | else if (WEXITSTATUS (wait_status) != 0) |
| 552 | exit (WRETCODE (wait_status)); | 543 | exit (WEXITSTATUS (wait_status)); |
| 553 | 544 | ||
| 554 | #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) | 545 | #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) |
| 555 | #ifdef MAIL_USE_MAILLOCK | 546 | #ifdef MAIL_USE_MAILLOCK |
| @@ -583,8 +574,8 @@ mail_spool_name (char *inname) | |||
| 583 | if (stat (MAILDIR, &stat1) < 0) | 574 | if (stat (MAILDIR, &stat1) < 0) |
| 584 | return NULL; | 575 | return NULL; |
| 585 | 576 | ||
| 586 | indir = (char *) xmalloc (fname - inname + 1); | 577 | indir = xmalloc (fname - inname + 1); |
| 587 | strncpy (indir, inname, fname - inname); | 578 | memcpy (indir, inname, fname - inname); |
| 588 | indir[fname-inname] = '\0'; | 579 | indir[fname-inname] = '\0'; |
| 589 | 580 | ||
| 590 | 581 | ||
| @@ -643,33 +634,6 @@ pfatal_and_delete (char *name) | |||
| 643 | unlink (name); | 634 | unlink (name); |
| 644 | fatal ("%s for %s", s, name); | 635 | fatal ("%s for %s", s, name); |
| 645 | } | 636 | } |
| 646 | |||
| 647 | /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ | ||
| 648 | |||
| 649 | static char * | ||
| 650 | concat (const char *s1, const char *s2, const char *s3) | ||
| 651 | { | ||
| 652 | size_t len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); | ||
| 653 | char *result = (char *) xmalloc (len1 + len2 + len3 + 1); | ||
| 654 | |||
| 655 | strcpy (result, s1); | ||
| 656 | strcpy (result + len1, s2); | ||
| 657 | strcpy (result + len1 + len2, s3); | ||
| 658 | *(result + len1 + len2 + len3) = 0; | ||
| 659 | |||
| 660 | return result; | ||
| 661 | } | ||
| 662 | |||
| 663 | /* Like malloc but get fatal error if memory is exhausted. */ | ||
| 664 | |||
| 665 | static long * | ||
| 666 | xmalloc (unsigned int size) | ||
| 667 | { | ||
| 668 | long *result = (long *) malloc (size); | ||
| 669 | if (!result) | ||
| 670 | fatal ("virtual memory exhausted", 0, 0); | ||
| 671 | return result; | ||
| 672 | } | ||
| 673 | 637 | ||
| 674 | /* This is the guts of the interface to the Post Office Protocol. */ | 638 | /* This is the guts of the interface to the Post Office Protocol. */ |
| 675 | 639 | ||
| @@ -851,10 +815,7 @@ pop_retr (popserver server, int msgno, FILE *arg) | |||
| 851 | 815 | ||
| 852 | if (pop_retrieve_first (server, msgno, &line)) | 816 | if (pop_retrieve_first (server, msgno, &line)) |
| 853 | { | 817 | { |
| 854 | char *msg = concat ("Error from POP server: ", pop_error, ""); | 818 | snprintf (Errmsg, sizeof Errmsg, "Error from POP server: %s", pop_error); |
| 855 | strncpy (Errmsg, msg, sizeof (Errmsg)); | ||
| 856 | Errmsg[sizeof (Errmsg)-1] = '\0'; | ||
| 857 | free (msg); | ||
| 858 | return (NOTOK); | 819 | return (NOTOK); |
| 859 | } | 820 | } |
| 860 | 821 | ||
| @@ -873,10 +834,7 @@ pop_retr (popserver server, int msgno, FILE *arg) | |||
| 873 | 834 | ||
| 874 | if (ret) | 835 | if (ret) |
| 875 | { | 836 | { |
| 876 | char *msg = concat ("Error from POP server: ", pop_error, ""); | 837 | snprintf (Errmsg, sizeof Errmsg, "Error from POP server: %s", pop_error); |
| 877 | strncpy (Errmsg, msg, sizeof (Errmsg)); | ||
| 878 | Errmsg[sizeof (Errmsg)-1] = '\0'; | ||
| 879 | free (msg); | ||
| 880 | return (NOTOK); | 838 | return (NOTOK); |
| 881 | } | 839 | } |
| 882 | 840 | ||
| @@ -939,21 +897,3 @@ mbx_delimit_end (FILE *mbf) | |||
| 939 | } | 897 | } |
| 940 | 898 | ||
| 941 | #endif /* MAIL_USE_POP */ | 899 | #endif /* MAIL_USE_POP */ |
| 942 | |||
| 943 | #ifndef HAVE_STRERROR | ||
| 944 | char * | ||
| 945 | strerror (errnum) | ||
| 946 | int errnum; | ||
| 947 | { | ||
| 948 | extern char *sys_errlist[]; | ||
| 949 | extern int sys_nerr; | ||
| 950 | |||
| 951 | if (errnum >= 0 && errnum < sys_nerr) | ||
| 952 | return sys_errlist[errnum]; | ||
| 953 | return (char *) "Unknown error"; | ||
| 954 | } | ||
| 955 | |||
| 956 | #endif /* ! HAVE_STRERROR */ | ||
| 957 | |||
| 958 | |||
| 959 | /* movemail.c ends here */ | ||