diff options
Diffstat (limited to 'lib-src/movemail.c')
| -rw-r--r-- | lib-src/movemail.c | 129 |
1 files changed, 77 insertions, 52 deletions
diff --git a/lib-src/movemail.c b/lib-src/movemail.c index 682aa10aa39..e8c09f090f3 100644 --- a/lib-src/movemail.c +++ b/lib-src/movemail.c | |||
| @@ -80,13 +80,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 80 | #undef access | 80 | #undef access |
| 81 | #endif /* MSDOS */ | 81 | #endif /* MSDOS */ |
| 82 | 82 | ||
| 83 | #ifndef DIRECTORY_SEP | ||
| 84 | #define DIRECTORY_SEP '/' | ||
| 85 | #endif | ||
| 86 | #ifndef IS_DIRECTORY_SEP | ||
| 87 | #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) | ||
| 88 | #endif | ||
| 89 | |||
| 90 | #ifdef WINDOWSNT | 83 | #ifdef WINDOWSNT |
| 91 | #include "ntlib.h" | 84 | #include "ntlib.h" |
| 92 | #undef access | 85 | #undef access |
| @@ -138,7 +131,7 @@ extern int lk_open (), lk_close (); | |||
| 138 | files appear in. */ | 131 | files appear in. */ |
| 139 | #ifdef MAILDIR | 132 | #ifdef MAILDIR |
| 140 | #define MAIL_USE_MAILLOCK | 133 | #define MAIL_USE_MAILLOCK |
| 141 | static char *mail_spool_name (); | 134 | static char *mail_spool_name (char *); |
| 142 | #endif | 135 | #endif |
| 143 | #endif | 136 | #endif |
| 144 | 137 | ||
| @@ -161,7 +154,7 @@ static int mbx_delimit_end (FILE *mbf); | |||
| 161 | #endif | 154 | #endif |
| 162 | 155 | ||
| 163 | /* Nonzero means this is name of a lock file to delete on fatal error. */ | 156 | /* Nonzero means this is name of a lock file to delete on fatal error. */ |
| 164 | char *delete_lockname; | 157 | static char *delete_lockname; |
| 165 | 158 | ||
| 166 | int | 159 | int |
| 167 | main (int argc, char **argv) | 160 | main (int argc, char **argv) |
| @@ -169,15 +162,15 @@ main (int argc, char **argv) | |||
| 169 | char *inname, *outname; | 162 | char *inname, *outname; |
| 170 | int indesc, outdesc; | 163 | int indesc, outdesc; |
| 171 | ssize_t nread; | 164 | ssize_t nread; |
| 172 | int status; | 165 | int wait_status; |
| 173 | int c, preserve_mail = 0; | 166 | int c, preserve_mail = 0; |
| 174 | 167 | ||
| 175 | #ifndef MAIL_USE_SYSTEM_LOCK | 168 | #ifndef MAIL_USE_SYSTEM_LOCK |
| 176 | struct stat st; | 169 | struct stat st; |
| 177 | long now; | ||
| 178 | int tem; | 170 | int tem; |
| 179 | char *lockname, *p; | 171 | char *lockname; |
| 180 | char *tempname; | 172 | char *tempname; |
| 173 | size_t inname_dirlen; | ||
| 181 | int desc; | 174 | int desc; |
| 182 | #endif /* not MAIL_USE_SYSTEM_LOCK */ | 175 | #endif /* not MAIL_USE_SYSTEM_LOCK */ |
| 183 | 176 | ||
| @@ -266,9 +259,22 @@ main (int argc, char **argv) | |||
| 266 | #ifndef MAIL_USE_SYSTEM_LOCK | 259 | #ifndef MAIL_USE_SYSTEM_LOCK |
| 267 | #ifdef MAIL_USE_MAILLOCK | 260 | #ifdef MAIL_USE_MAILLOCK |
| 268 | spool_name = mail_spool_name (inname); | 261 | spool_name = mail_spool_name (inname); |
| 269 | if (! spool_name) | 262 | if (spool_name) |
| 263 | { | ||
| 264 | #ifdef lint | ||
| 265 | lockname = 0; | ||
| 266 | #endif | ||
| 267 | } | ||
| 268 | else | ||
| 270 | #endif | 269 | #endif |
| 271 | { | 270 | { |
| 271 | #ifndef DIRECTORY_SEP | ||
| 272 | #define DIRECTORY_SEP '/' | ||
| 273 | #endif | ||
| 274 | #ifndef IS_DIRECTORY_SEP | ||
| 275 | #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) | ||
| 276 | #endif | ||
| 277 | |||
| 272 | /* Use a lock file named after our first argument with .lock appended: | 278 | /* Use a lock file named after our first argument with .lock appended: |
| 273 | If it exists, the mail file is locked. */ | 279 | If it exists, the mail file is locked. */ |
| 274 | /* Note: this locking mechanism is *required* by the mailer | 280 | /* Note: this locking mechanism is *required* by the mailer |
| @@ -293,26 +299,38 @@ main (int argc, char **argv) | |||
| 293 | to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ | 299 | to bug-gnu-emacs@prep.ai.mit.edu so we can fix it. */ |
| 294 | 300 | ||
| 295 | lockname = concat (inname, ".lock", ""); | 301 | lockname = concat (inname, ".lock", ""); |
| 296 | tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); | 302 | for (inname_dirlen = strlen (inname); |
| 297 | strcpy (tempname, inname); | 303 | inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]); |
| 298 | p = tempname + strlen (tempname); | 304 | inname_dirlen--) |
| 299 | while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) | 305 | continue; |
| 300 | p--; | 306 | tempname = (char *) xmalloc (inname_dirlen + sizeof "EXXXXXX"); |
| 301 | *p = 0; | ||
| 302 | strcpy (p, "EXXXXXX"); | ||
| 303 | mktemp (tempname); | ||
| 304 | unlink (tempname); | ||
| 305 | 307 | ||
| 306 | while (1) | 308 | while (1) |
| 307 | { | 309 | { |
| 308 | /* Create the lock file, but not under the lock file name. */ | 310 | /* Create the lock file, but not under the lock file name. */ |
| 309 | /* Give up if cannot do that. */ | 311 | /* Give up if cannot do that. */ |
| 310 | desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0666); | 312 | |
| 313 | memcpy (tempname, inname, inname_dirlen); | ||
| 314 | strcpy (tempname + inname_dirlen, "EXXXXXX"); | ||
| 315 | #ifdef HAVE_MKSTEMP | ||
| 316 | desc = mkstemp (tempname); | ||
| 317 | #else | ||
| 318 | mktemp (tempname); | ||
| 319 | if (!*tempname) | ||
| 320 | desc = -1; | ||
| 321 | else | ||
| 322 | { | ||
| 323 | unlink (tempname); | ||
| 324 | desc = open (tempname, O_WRONLY | O_CREAT | O_EXCL, 0600); | ||
| 325 | } | ||
| 326 | #endif | ||
| 311 | if (desc < 0) | 327 | if (desc < 0) |
| 312 | { | 328 | { |
| 329 | int mkstemp_errno = errno; | ||
| 313 | char *message = (char *) xmalloc (strlen (tempname) + 50); | 330 | char *message = (char *) xmalloc (strlen (tempname) + 50); |
| 314 | sprintf (message, "creating %s, which would become the lock file", | 331 | sprintf (message, "creating %s, which would become the lock file", |
| 315 | tempname); | 332 | tempname); |
| 333 | errno = mkstemp_errno; | ||
| 316 | pfatal_with_name (message); | 334 | pfatal_with_name (message); |
| 317 | } | 335 | } |
| 318 | close (desc); | 336 | close (desc); |
| @@ -336,7 +354,7 @@ main (int argc, char **argv) | |||
| 336 | by time differences between machines. */ | 354 | by time differences between machines. */ |
| 337 | if (stat (lockname, &st) >= 0) | 355 | if (stat (lockname, &st) >= 0) |
| 338 | { | 356 | { |
| 339 | now = time (0); | 357 | time_t now = time (0); |
| 340 | if (st.st_ctime < now - 300) | 358 | if (st.st_ctime < now - 300) |
| 341 | unlink (lockname); | 359 | unlink (lockname); |
| 342 | } | 360 | } |
| @@ -352,7 +370,10 @@ main (int argc, char **argv) | |||
| 352 | int lockcount = 0; | 370 | int lockcount = 0; |
| 353 | int status = 0; | 371 | int status = 0; |
| 354 | #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) | 372 | #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) |
| 355 | time_t touched_lock, now; | 373 | time_t touched_lock; |
| 374 | # ifdef lint | ||
| 375 | touched_lock = 0; | ||
| 376 | # endif | ||
| 356 | #endif | 377 | #endif |
| 357 | 378 | ||
| 358 | if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0) | 379 | if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0) |
| @@ -462,7 +483,7 @@ main (int argc, char **argv) | |||
| 462 | #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) | 483 | #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK) |
| 463 | if (spool_name) | 484 | if (spool_name) |
| 464 | { | 485 | { |
| 465 | now = time (0); | 486 | time_t now = time (0); |
| 466 | if (now - touched_lock > 60) | 487 | if (now - touched_lock > 60) |
| 467 | { | 488 | { |
| 468 | touchlock (); | 489 | touchlock (); |
| @@ -527,11 +548,11 @@ main (int argc, char **argv) | |||
| 527 | exit (EXIT_SUCCESS); | 548 | exit (EXIT_SUCCESS); |
| 528 | } | 549 | } |
| 529 | 550 | ||
| 530 | wait (&status); | 551 | wait (&wait_status); |
| 531 | if (!WIFEXITED (status)) | 552 | if (!WIFEXITED (wait_status)) |
| 532 | exit (EXIT_FAILURE); | 553 | exit (EXIT_FAILURE); |
| 533 | else if (WRETCODE (status) != 0) | 554 | else if (WRETCODE (wait_status) != 0) |
| 534 | exit (WRETCODE (status)); | 555 | exit (WRETCODE (wait_status)); |
| 535 | 556 | ||
| 536 | #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) | 557 | #if !defined (MAIL_USE_MMDF) && !defined (MAIL_USE_SYSTEM_LOCK) |
| 537 | #ifdef MAIL_USE_MAILLOCK | 558 | #ifdef MAIL_USE_MAILLOCK |
| @@ -670,14 +691,8 @@ xmalloc (unsigned int size) | |||
| 670 | 691 | ||
| 671 | #define NOTOK (-1) | 692 | #define NOTOK (-1) |
| 672 | #define OK 0 | 693 | #define OK 0 |
| 673 | #define DONE 1 | 694 | |
| 674 | 695 | static char Errmsg[200]; /* POP errors, at least, can exceed | |
| 675 | char *progname; | ||
| 676 | FILE *sfi; | ||
| 677 | FILE *sfo; | ||
| 678 | char ibuffer[BUFSIZ]; | ||
| 679 | char obuffer[BUFSIZ]; | ||
| 680 | char Errmsg[200]; /* POP errors, at least, can exceed | ||
| 681 | the original length of 80. */ | 696 | the original length of 80. */ |
| 682 | 697 | ||
| 683 | /* | 698 | /* |
| @@ -736,7 +751,18 @@ popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse | |||
| 736 | error ("Error in open: %s, %s", strerror (errno), outfile); | 751 | error ("Error in open: %s, %s", strerror (errno), outfile); |
| 737 | return EXIT_FAILURE; | 752 | return EXIT_FAILURE; |
| 738 | } | 753 | } |
| 739 | fchown (mbfi, getuid (), -1); | 754 | |
| 755 | if (fchown (mbfi, getuid (), -1) != 0) | ||
| 756 | { | ||
| 757 | int fchown_errno = errno; | ||
| 758 | struct stat st; | ||
| 759 | if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ()) | ||
| 760 | { | ||
| 761 | pop_close (server); | ||
| 762 | error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile); | ||
| 763 | return EXIT_FAILURE; | ||
| 764 | } | ||
| 765 | } | ||
| 740 | 766 | ||
| 741 | if ((mbf = fdopen (mbfi, "wb")) == NULL) | 767 | if ((mbf = fdopen (mbfi, "wb")) == NULL) |
| 742 | { | 768 | { |
| @@ -828,10 +854,10 @@ pop_retr (popserver server, int msgno, FILE *arg) | |||
| 828 | 854 | ||
| 829 | if (pop_retrieve_first (server, msgno, &line)) | 855 | if (pop_retrieve_first (server, msgno, &line)) |
| 830 | { | 856 | { |
| 831 | char *error = concat ("Error from POP server: ", pop_error, ""); | 857 | char *msg = concat ("Error from POP server: ", pop_error, ""); |
| 832 | strncpy (Errmsg, error, sizeof (Errmsg)); | 858 | strncpy (Errmsg, msg, sizeof (Errmsg)); |
| 833 | Errmsg[sizeof (Errmsg)-1] = '\0'; | 859 | Errmsg[sizeof (Errmsg)-1] = '\0'; |
| 834 | free(error); | 860 | free (msg); |
| 835 | return (NOTOK); | 861 | return (NOTOK); |
| 836 | } | 862 | } |
| 837 | 863 | ||
| @@ -850,27 +876,26 @@ pop_retr (popserver server, int msgno, FILE *arg) | |||
| 850 | 876 | ||
| 851 | if (ret) | 877 | if (ret) |
| 852 | { | 878 | { |
| 853 | char *error = concat ("Error from POP server: ", pop_error, ""); | 879 | char *msg = concat ("Error from POP server: ", pop_error, ""); |
| 854 | strncpy (Errmsg, error, sizeof (Errmsg)); | 880 | strncpy (Errmsg, msg, sizeof (Errmsg)); |
| 855 | Errmsg[sizeof (Errmsg)-1] = '\0'; | 881 | Errmsg[sizeof (Errmsg)-1] = '\0'; |
| 856 | free(error); | 882 | free (msg); |
| 857 | return (NOTOK); | 883 | return (NOTOK); |
| 858 | } | 884 | } |
| 859 | 885 | ||
| 860 | return (OK); | 886 | return (OK); |
| 861 | } | 887 | } |
| 862 | 888 | ||
| 863 | /* Do this as a macro instead of using strcmp to save on execution time. */ | ||
| 864 | #define IS_FROM_LINE(a) ((a[0] == 'F') \ | ||
| 865 | && (a[1] == 'r') \ | ||
| 866 | && (a[2] == 'o') \ | ||
| 867 | && (a[3] == 'm') \ | ||
| 868 | && (a[4] == ' ')) | ||
| 869 | |||
| 870 | static int | 889 | static int |
| 871 | mbx_write (char *line, int len, FILE *mbf) | 890 | mbx_write (char *line, int len, FILE *mbf) |
| 872 | { | 891 | { |
| 873 | #ifdef MOVEMAIL_QUOTE_POP_FROM_LINES | 892 | #ifdef MOVEMAIL_QUOTE_POP_FROM_LINES |
| 893 | /* Do this as a macro instead of using strcmp to save on execution time. */ | ||
| 894 | # define IS_FROM_LINE(a) ((a[0] == 'F') \ | ||
| 895 | && (a[1] == 'r') \ | ||
| 896 | && (a[2] == 'o') \ | ||
| 897 | && (a[3] == 'm') \ | ||
| 898 | && (a[4] == ' ')) | ||
| 874 | if (IS_FROM_LINE (line)) | 899 | if (IS_FROM_LINE (line)) |
| 875 | { | 900 | { |
| 876 | if (fputc ('>', mbf) == EOF) | 901 | if (fputc ('>', mbf) == EOF) |