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 *