Mercurial > emacs
comparison lib-src/movemail.c @ 447:2e226dcdaf0f
*** empty log message ***
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sat, 07 Dec 1991 22:01:44 +0000 |
parents | 5729b1cc3942 |
children | 4eaef1578a15 |
comparison
equal
deleted
inserted
replaced
446:76b7a95526d3 | 447:2e226dcdaf0f |
---|---|
27 * a pop server running on $MAILHOST (environment variable). Movemail | 27 * a pop server running on $MAILHOST (environment variable). Movemail |
28 * must be setuid to root in order to work with POP. | 28 * must be setuid to root in order to work with POP. |
29 * | 29 * |
30 * New module: popmail.c | 30 * New module: popmail.c |
31 * Modified routines: | 31 * Modified routines: |
32 * main - added code within #ifdef MAIL_USE_POP; added setuid(getuid()) | 32 * main - added code within #ifdef MAIL_USE_POP; added setuid (getuid ()) |
33 * after POP code. | 33 * after POP code. |
34 * New routines in movemail.c: | 34 * New routines in movemail.c: |
35 * get_errmsg - return pointer to system error message | 35 * get_errmsg - return pointer to system error message |
36 * | 36 * |
37 */ | 37 */ |
131 user = (char *) rindex (inname, ':') + 1; | 131 user = (char *) rindex (inname, ':') + 1; |
132 status = popmail (user, outname); | 132 status = popmail (user, outname); |
133 exit (status); | 133 exit (status); |
134 } | 134 } |
135 | 135 |
136 setuid (getuid()); | 136 setuid (getuid ()); |
137 #endif /* MAIL_USE_POP */ | 137 #endif /* MAIL_USE_POP */ |
138 | 138 |
139 /* Check access to input file. */ | 139 /* Check access to input file. */ |
140 if (access (inname, R_OK | W_OK) != 0) | 140 if (access (inname, R_OK | W_OK) != 0) |
141 pfatal_with_name (inname); | 141 pfatal_with_name (inname); |
171 while (p != tempname && p[-1] != '/') | 171 while (p != tempname && p[-1] != '/') |
172 p--; | 172 p--; |
173 *p = 0; | 173 *p = 0; |
174 strcpy (p, "EXXXXXX"); | 174 strcpy (p, "EXXXXXX"); |
175 mktemp (tempname); | 175 mktemp (tempname); |
176 (void) unlink (tempname); | 176 unlink (tempname); |
177 | 177 |
178 while (1) | 178 while (1) |
179 { | 179 { |
180 /* Create the lock file, but not under the lock file name. */ | 180 /* Create the lock file, but not under the lock file name. */ |
181 /* Give up if cannot do that. */ | 181 /* Give up if cannot do that. */ |
183 if (desc < 0) | 183 if (desc < 0) |
184 pfatal_with_name ("lock file--see source file etc/movemail.c"); | 184 pfatal_with_name ("lock file--see source file etc/movemail.c"); |
185 close (desc); | 185 close (desc); |
186 | 186 |
187 tem = link (tempname, lockname); | 187 tem = link (tempname, lockname); |
188 (void) unlink (tempname); | 188 unlink (tempname); |
189 if (tem >= 0) | 189 if (tem >= 0) |
190 break; | 190 break; |
191 sleep (1); | 191 sleep (1); |
192 | 192 |
193 /* If lock file is a minute old, unlock it. */ | 193 /* If lock file is a minute old, unlock it. */ |
194 if (stat (lockname, &st) >= 0) | 194 if (stat (lockname, &st) >= 0) |
195 { | 195 { |
196 now = time (0); | 196 now = time (0); |
197 if (st.st_ctime < now - 60) | 197 if (st.st_ctime < now - 60) |
198 (void) unlink (lockname); | 198 unlink (lockname); |
199 } | 199 } |
200 } | 200 } |
201 | 201 |
202 delete_lockname = lockname; | 202 delete_lockname = lockname; |
203 #endif /* not MAIL_USE_FLOCK */ | 203 #endif /* not MAIL_USE_FLOCK */ |
212 #endif /* MAIL_USE_MMDF */ | 212 #endif /* MAIL_USE_MMDF */ |
213 | 213 |
214 if (indesc < 0) | 214 if (indesc < 0) |
215 pfatal_with_name (inname); | 215 pfatal_with_name (inname); |
216 | 216 |
217 #if defined(BSD) || defined(XENIX) | 217 #if defined (BSD) || defined (XENIX) |
218 /* In case movemail is setuid to root, make sure the user can | 218 /* In case movemail is setuid to root, make sure the user can |
219 read the output file. */ | 219 read the output file. */ |
220 /* This is desirable for all systems | 220 /* This is desirable for all systems |
221 but I don't want to assume all have the umask system call */ | 221 but I don't want to assume all have the umask system call */ |
222 umask (umask (0) & 0333); | 222 umask (umask (0) & 0333); |
236 { | 236 { |
237 nread = read (indesc, buf, sizeof buf); | 237 nread = read (indesc, buf, sizeof buf); |
238 if (nread != write (outdesc, buf, nread)) | 238 if (nread != write (outdesc, buf, nread)) |
239 { | 239 { |
240 int saved_errno = errno; | 240 int saved_errno = errno; |
241 (void) unlink (outname); | 241 unlink (outname); |
242 errno = saved_errno; | 242 errno = saved_errno; |
243 pfatal_with_name (outname); | 243 pfatal_with_name (outname); |
244 } | 244 } |
245 if (nread < sizeof buf) | 245 if (nread < sizeof buf) |
246 break; | 246 break; |
247 } | 247 } |
248 | 248 |
249 #ifdef BSD | 249 #ifdef BSD |
250 fsync (outdesc); | 250 if (fsync (outdesc) < 0) |
251 pfatal_and_delete (outname); | |
251 #endif | 252 #endif |
252 | 253 |
253 /* Check to make sure no errors before we zap the inbox. */ | 254 /* Check to make sure no errors before we zap the inbox. */ |
254 if (close (outdesc) != 0) | 255 if (close (outdesc) != 0) |
255 { | 256 pfatal_and_delete (outname); |
256 int saved_errno = errno; | |
257 (void) unlink (outname); | |
258 errno = saved_errno; | |
259 pfatal_with_name (outname); | |
260 } | |
261 | 257 |
262 #ifdef MAIL_USE_FLOCK | 258 #ifdef MAIL_USE_FLOCK |
263 #if defined(STRIDE) || defined(XENIX) | 259 #if defined (STRIDE) || defined (XENIX) |
264 /* Stride, xenix have file locking, but no ftruncate. This mess will do. */ | 260 /* Stride, xenix have file locking, but no ftruncate. This mess will do. */ |
265 (void) close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666)); | 261 close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666)); |
266 #else | 262 #else |
267 (void) ftruncate (indesc, 0L); | 263 ftruncate (indesc, 0L); |
268 #endif /* STRIDE or XENIX */ | 264 #endif /* STRIDE or XENIX */ |
269 #endif /* MAIL_USE_FLOCK */ | 265 #endif /* MAIL_USE_FLOCK */ |
270 | 266 |
271 #ifdef MAIL_USE_MMDF | 267 #ifdef MAIL_USE_MMDF |
272 lk_close (indesc, 0, 0, 0); | 268 lk_close (indesc, 0, 0, 0); |
319 else | 315 else |
320 s = "cannot open %s"; | 316 s = "cannot open %s"; |
321 fatal (s, name); | 317 fatal (s, name); |
322 } | 318 } |
323 | 319 |
320 pfatal_and_delete (name) | |
321 char *name; | |
322 { | |
323 extern int errno, sys_nerr; | |
324 extern char *sys_errlist[]; | |
325 char *s; | |
326 | |
327 if (errno < sys_nerr) | |
328 s = concat ("", sys_errlist[errno], " for %s"); | |
329 else | |
330 s = "cannot open %s"; | |
331 | |
332 unlink (name); | |
333 fatal (s, name); | |
334 } | |
335 | |
324 /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ | 336 /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ |
325 | 337 |
326 char * | 338 char * |
327 concat (s1, s2, s3) | 339 concat (s1, s2, s3) |
328 char *s1, *s2, *s3; | 340 char *s1, *s2, *s3; |
400 fatal ("no MAILHOST defined"); | 412 fatal ("no MAILHOST defined"); |
401 } | 413 } |
402 | 414 |
403 if (pop_init (host) == NOTOK) | 415 if (pop_init (host) == NOTOK) |
404 { | 416 { |
405 error (Errmsg); | 417 fatal (Errmsg); |
406 return 1; | |
407 } | 418 } |
408 | 419 |
409 if (getline (response, sizeof response, sfi) != OK) | 420 if (getline (response, sizeof response, sfi) != OK) |
410 { | 421 { |
411 error (response); | 422 fatal (response); |
412 return 1; | 423 } |
413 } | 424 |
414 | 425 if (pop_command ("USER %s", user) == NOTOK |
415 if (pop_command ("USER %s", user) == NOTOK | |
416 || pop_command ("RPOP %s", user) == NOTOK) | 426 || pop_command ("RPOP %s", user) == NOTOK) |
417 { | 427 { |
418 error (Errmsg); | |
419 pop_command ("QUIT"); | 428 pop_command ("QUIT"); |
420 return 1; | 429 fatal (Errmsg); |
421 } | 430 } |
422 | 431 |
423 if (pop_stat (&nmsgs, &nbytes) == NOTOK) | 432 if (pop_stat (&nmsgs, &nbytes) == NOTOK) |
424 { | 433 { |
425 error (Errmsg); | |
426 pop_command ("QUIT"); | 434 pop_command ("QUIT"); |
427 return 1; | 435 fatal (Errmsg); |
428 } | 436 } |
429 | 437 |
430 if (!nmsgs) | 438 if (!nmsgs) |
431 { | 439 { |
432 pop_command ("QUIT"); | 440 pop_command ("QUIT"); |
435 | 443 |
436 mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); | 444 mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); |
437 if (mbfi < 0) | 445 if (mbfi < 0) |
438 { | 446 { |
439 pop_command ("QUIT"); | 447 pop_command ("QUIT"); |
440 error ("Error in open: %s, %s", get_errmsg (), outfile); | 448 pfatal_and_delete (outfile); |
441 return 1; | |
442 } | 449 } |
443 fchown (mbfi, getuid (), -1); | 450 fchown (mbfi, getuid (), -1); |
444 | 451 |
445 if ((mbf = fdopen (mbfi, "w")) == NULL) | 452 if ((mbf = fdopen (mbfi, "w")) == NULL) |
446 { | 453 { |
447 pop_command ("QUIT"); | 454 pop_command ("QUIT"); |
448 error ("Error in fdopen: %s", get_errmsg ()); | 455 pfatal_and_delete (outfile); |
449 close (mbfi); | |
450 unlink (outfile); | |
451 return 1; | |
452 } | 456 } |
453 | 457 |
454 for (i = 1; i <= nmsgs; i++) | 458 for (i = 1; i <= nmsgs; i++) |
455 { | 459 { |
456 mbx_delimit_begin (mbf); | 460 mbx_delimit_begin (mbf); |
457 if (pop_retr (i, mbx_write, mbf) != OK) | 461 if (pop_retr (i, mbx_write, mbf) != OK) |
458 { | 462 { |
459 error (Errmsg); | |
460 pop_command ("QUIT"); | 463 pop_command ("QUIT"); |
461 close (mbfi); | 464 close (mbfi); |
462 return 1; | 465 unlink (outfile); |
466 fatal (Errmsg); | |
463 } | 467 } |
464 mbx_delimit_end (mbf); | 468 mbx_delimit_end (mbf); |
465 fflush (mbf); | 469 fflush (mbf); |
466 } | 470 } |
467 | 471 |
472 if (fsync (mbfi) < 0) | |
473 { | |
474 pop_command ("QUIT"); | |
475 pfatal_and_delete (outfile); | |
476 } | |
477 | |
478 if (close (mbfi) == -1) | |
479 { | |
480 pop_command ("QUIT"); | |
481 pfatal_and_delete (outfile); | |
482 } | |
483 | |
468 for (i = 1; i <= nmsgs; i++) | 484 for (i = 1; i <= nmsgs; i++) |
469 { | 485 { |
470 if (pop_command ("DELE %d", i) == NOTOK) | 486 if (pop_command ("DELE %d", i) == NOTOK) |
471 { | 487 { |
472 error (Errmsg); | 488 /* Better to ignore this failure. */ |
473 pop_command ("QUIT"); | |
474 close (mbfi); | |
475 return 1; | |
476 } | 489 } |
477 } | 490 } |
478 | 491 |
479 pop_command ("QUIT"); | 492 pop_command ("QUIT"); |
480 close (mbfi); | 493 return (0); |
481 return 0; | |
482 } | 494 } |
483 | 495 |
484 pop_init (host) | 496 pop_init (host) |
485 char *host; | 497 char *host; |
486 { | 498 { |
548 { | 560 { |
549 strcpy (Errmsg, buf); | 561 strcpy (Errmsg, buf); |
550 return NOTOK; | 562 return NOTOK; |
551 } | 563 } |
552 | 564 |
553 if (debug) fprintf (stderr, "<--- %s\n", buf); | 565 if (debug) |
566 fprintf (stderr, "<--- %s\n", buf); | |
554 if (*buf != '+') | 567 if (*buf != '+') |
555 { | 568 { |
556 strcpy (Errmsg, buf); | 569 strcpy (Errmsg, buf); |
557 return NOTOK; | 570 return NOTOK; |
558 } | 571 } |
566 pop_stat (nmsgs, nbytes) | 579 pop_stat (nmsgs, nbytes) |
567 int *nmsgs, *nbytes; | 580 int *nmsgs, *nbytes; |
568 { | 581 { |
569 char buf[128]; | 582 char buf[128]; |
570 | 583 |
571 if (debug) fprintf (stderr, "---> STAT\n"); | 584 if (debug) |
572 if (putline ("STAT", Errmsg, sfo) == NOTOK) return NOTOK; | 585 fprintf (stderr, "---> STAT\n"); |
586 if (putline ("STAT", Errmsg, sfo) == NOTOK) | |
587 return NOTOK; | |
573 | 588 |
574 if (getline (buf, sizeof buf, sfi) != OK) | 589 if (getline (buf, sizeof buf, sfi) != OK) |
575 { | 590 { |
576 strcpy (Errmsg, buf); | 591 strcpy (Errmsg, buf); |
577 return NOTOK; | 592 return NOTOK; |
654 multiline (buf, n, f) | 669 multiline (buf, n, f) |
655 char *buf; | 670 char *buf; |
656 register int n; | 671 register int n; |
657 FILE *f; | 672 FILE *f; |
658 { | 673 { |
659 if (getline (buf, n, f) != OK) return NOTOK; | 674 if (getline (buf, n, f) != OK) |
675 return NOTOK; | |
660 if (*buf == '.') | 676 if (*buf == '.') |
661 { | 677 { |
662 if (*(buf+1) == NULL) | 678 if (*(buf+1) == NULL) |
663 { | 679 return DONE; |
664 return DONE; | |
665 } | |
666 else | 680 else |
667 { | 681 strcpy (buf, buf+1); |
668 strcpy (buf, buf+1); | |
669 } | |
670 } | 682 } |
671 return OK; | 683 return OK; |
672 } | 684 } |
673 | 685 |
674 char * | 686 char * |