|
|
1.1 ! root 1: /* movemail foo bar -- move file foo to file bar, ! 2: locking file foo the way /bin/mail respects. ! 3: Copyright (C) 1986 Free Software Foundation, Inc. ! 4: ! 5: This file is part of GNU Emacs. ! 6: ! 7: GNU Emacs is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 1, or (at your option) ! 10: any later version. ! 11: ! 12: GNU Emacs is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU Emacs; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: /* Important notice: defining MAIL_USE_FLOCK *will cause loss of mail* ! 22: if you do it on a system that does not normally use flock as its way of ! 23: interlocking access to inbox files. The setting of MAIL_USE_FLOCK ! 24: *must agree* with the system's own conventions. ! 25: It is not a choice that is up to you. ! 26: ! 27: So, if your system uses lock files rather than flock, then the only way ! 28: you can get proper operation is to enable movemail to write lockfiles there. ! 29: This means you must either give that directory access modes ! 30: that permit everyone to write lockfiles in it, or you must make movemail ! 31: a setuid or setgid program. */ ! 32: ! 33: /* ! 34: * Modified January, 1986 by Michael R. Gretzinger (Project Athena) ! 35: * ! 36: * Added POP (Post Office Protocol) service. When compiled -DPOP ! 37: * movemail will accept input filename arguments of the form ! 38: * "po:username". This will cause movemail to open a connection to ! 39: * a pop server running on $MAILHOST (environment variable). Movemail ! 40: * must be setuid to root in order to work with POP. ! 41: * ! 42: * New module: popmail.c ! 43: * Modified routines: ! 44: * main - added code within #ifdef MAIL_USE_POP; added setuid (getuid ()) ! 45: * after POP code. ! 46: * New routines in movemail.c: ! 47: * get_errmsg - return pointer to system error message ! 48: * ! 49: */ ! 50: ! 51: #include <sys/types.h> ! 52: #include <sys/stat.h> ! 53: #include <sys/file.h> ! 54: #include <errno.h> ! 55: #define NO_SHORTNAMES /* Tell config not to load remap.h */ ! 56: #include "../src/config.h" ! 57: ! 58: #ifdef USG ! 59: #include <fcntl.h> ! 60: #include <unistd.h> ! 61: #ifndef F_OK ! 62: #define F_OK 0 ! 63: #define X_OK 1 ! 64: #define W_OK 2 ! 65: #define R_OK 4 ! 66: #endif ! 67: #endif /* USG */ ! 68: ! 69: #ifdef XENIX ! 70: #include <sys/locking.h> ! 71: #endif ! 72: ! 73: #ifdef MAIL_USE_MMDF ! 74: extern int lk_open (), lk_close (); ! 75: #endif ! 76: ! 77: /* Cancel substitutions made by config.h for Emacs. */ ! 78: #undef open ! 79: #undef read ! 80: #undef write ! 81: #undef close ! 82: ! 83: char *concat (); ! 84: extern int errno; ! 85: ! 86: /* Nonzero means this is name of a lock file to delete on fatal error. */ ! 87: char *delete_lockname; ! 88: ! 89: main (argc, argv) ! 90: int argc; ! 91: char **argv; ! 92: { ! 93: char *inname, *outname; ! 94: int indesc, outdesc; ! 95: char buf[1024]; ! 96: int nread; ! 97: ! 98: #ifndef MAIL_USE_FLOCK ! 99: struct stat st; ! 100: long now; ! 101: int tem; ! 102: char *lockname, *p; ! 103: char *tempname; ! 104: int desc; ! 105: #endif /* not MAIL_USE_FLOCK */ ! 106: ! 107: delete_lockname = 0; ! 108: ! 109: if (argc < 3) ! 110: fatal ("two arguments required"); ! 111: ! 112: inname = argv[1]; ! 113: outname = argv[2]; ! 114: ! 115: #ifdef MAIL_USE_MMDF ! 116: mmdf_init (argv[0]); ! 117: #endif ! 118: ! 119: /* Check access to output file. */ ! 120: if (access (outname, F_OK) == 0 && access (outname, W_OK) != 0) ! 121: pfatal_with_name (outname); ! 122: ! 123: /* Also check that outname's directory is writeable to the real uid. */ ! 124: { ! 125: char *buf = (char *) malloc (strlen (outname) + 1); ! 126: char *p, q; ! 127: strcpy (buf, outname); ! 128: p = buf + strlen (buf); ! 129: while (p > buf && p[-1] != '/') ! 130: *--p = 0; ! 131: if (p == buf) ! 132: *p++ = '.'; ! 133: if (access (buf, W_OK) != 0) ! 134: pfatal_with_name (buf); ! 135: free (buf); ! 136: } ! 137: ! 138: #ifdef MAIL_USE_POP ! 139: if (!bcmp (inname, "po:", 3)) ! 140: { ! 141: int status; char *user; ! 142: ! 143: user = (char *) rindex (inname, ':') + 1; ! 144: status = popmail (user, outname); ! 145: exit (status); ! 146: } ! 147: ! 148: setuid (getuid ()); ! 149: #endif /* MAIL_USE_POP */ ! 150: ! 151: /* Check access to input file. */ ! 152: if (access (inname, R_OK | W_OK) != 0) ! 153: pfatal_with_name (inname); ! 154: ! 155: #ifndef MAIL_USE_MMDF ! 156: #ifndef MAIL_USE_FLOCK ! 157: /* Use a lock file named /usr/spool/mail/$USER.lock: ! 158: If it exists, the mail file is locked. */ ! 159: /* Note: this locking mechanism is *required* by the mailer ! 160: (on systems which use it) to prevent loss of mail. ! 161: ! 162: On systems that use a lock file, extracting the mail without locking ! 163: WILL occasionally cause loss of mail due to timing errors! ! 164: ! 165: So, if creation of the lock file fails ! 166: due to access permission on /usr/spool/mail, ! 167: you simply MUST change the permission ! 168: and/or make movemail a setgid program ! 169: so it can create lock files properly. ! 170: ! 171: You might also wish to verify that your system is one ! 172: which uses lock files for this purpose. Some systems use other methods. ! 173: ! 174: If your system uses the `flock' system call for mail locking, ! 175: define MAIL_USE_FLOCK in config.h or the s-*.h file ! 176: and recompile movemail. If the s- file for your system ! 177: should define MAIL_USE_FLOCK but does not, send a bug report ! 178: to [email protected] so we can fix it. */ ! 179: ! 180: lockname = concat (inname, ".lock", ""); ! 181: tempname = (char *) xmalloc (strlen (inname) + 20); ! 182: strcpy (tempname, inname); ! 183: p = tempname + strlen (tempname); ! 184: while (p != tempname && p[-1] != '/') ! 185: p--; ! 186: *p = 0; ! 187: strcpy (p, "EXXXXXX"); ! 188: mktemp (tempname); ! 189: unlink (tempname); ! 190: ! 191: while (1) ! 192: { ! 193: /* Create the lock file, but not under the lock file name. */ ! 194: /* Give up if cannot do that. */ ! 195: desc = open (tempname, O_WRONLY | O_CREAT, 0666); ! 196: if (desc < 0) ! 197: pfatal_with_name ("lock file--see source file etc/movemail.c"); ! 198: close (desc); ! 199: ! 200: tem = link (tempname, lockname); ! 201: unlink (tempname); ! 202: if (tem >= 0) ! 203: break; ! 204: sleep (1); ! 205: ! 206: /* If lock file is a minute old, unlock it. */ ! 207: if (stat (lockname, &st) >= 0) ! 208: { ! 209: now = time (0); ! 210: if (st.st_ctime < now - 60) ! 211: unlink (lockname); ! 212: } ! 213: } ! 214: ! 215: delete_lockname = lockname; ! 216: #endif /* not MAIL_USE_FLOCK */ ! 217: ! 218: #ifdef MAIL_USE_FLOCK ! 219: indesc = open (inname, O_RDWR); ! 220: #else /* if not MAIL_USE_FLOCK */ ! 221: indesc = open (inname, O_RDONLY); ! 222: #endif /* not MAIL_USE_FLOCK */ ! 223: #else /* MAIL_USE_MMDF */ ! 224: indesc = lk_open (inname, O_RDONLY, 0, 0, 10); ! 225: #endif /* MAIL_USE_MMDF */ ! 226: ! 227: if (indesc < 0) ! 228: pfatal_with_name (inname); ! 229: ! 230: #if defined (BSD) || defined (XENIX) ! 231: /* In case movemail is setuid to root, make sure the user can ! 232: read the output file. */ ! 233: /* This is desirable for all systems ! 234: but I don't want to assume all have the umask system call */ ! 235: umask (umask (0) & 0333); ! 236: #endif /* BSD or Xenix */ ! 237: outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666); ! 238: if (outdesc < 0) ! 239: pfatal_with_name (outname); ! 240: #ifdef MAIL_USE_FLOCK ! 241: #ifdef XENIX ! 242: if (locking (indesc, LK_RLCK, 0L) < 0) pfatal_with_name (inname); ! 243: #else ! 244: if (flock (indesc, LOCK_EX) < 0) pfatal_with_name (inname); ! 245: #endif ! 246: #endif /* MAIL_USE_FLOCK */ ! 247: ! 248: while (1) ! 249: { ! 250: nread = read (indesc, buf, sizeof buf); ! 251: if (nread != write (outdesc, buf, nread)) ! 252: { ! 253: int saved_errno = errno; ! 254: unlink (outname); ! 255: errno = saved_errno; ! 256: pfatal_with_name (outname); ! 257: } ! 258: if (nread < sizeof buf) ! 259: break; ! 260: } ! 261: ! 262: #ifdef BSD ! 263: if (fsync (outdesc) < 0) ! 264: pfatal_and_delete (outname); ! 265: #endif ! 266: ! 267: /* Check to make sure no errors before we zap the inbox. */ ! 268: if (close (outdesc) != 0) ! 269: pfatal_and_delete (outname); ! 270: ! 271: #ifdef MAIL_USE_FLOCK ! 272: #if defined (STRIDE) || defined (XENIX) ! 273: /* Stride, xenix have file locking, but no ftruncate. This mess will do. */ ! 274: close (open (inname, O_CREAT | O_TRUNC | O_RDWR, 0666)); ! 275: #else ! 276: ftruncate (indesc, 0L); ! 277: #endif /* STRIDE or XENIX */ ! 278: #endif /* MAIL_USE_FLOCK */ ! 279: ! 280: #ifdef MAIL_USE_MMDF ! 281: lk_close (indesc, 0, 0, 0); ! 282: #else ! 283: close (indesc); ! 284: #endif ! 285: ! 286: #ifndef MAIL_USE_FLOCK ! 287: /* Delete the input file; if we can't, at least get rid of its contents. */ ! 288: if (unlink (inname) < 0) ! 289: if (errno != ENOENT) ! 290: creat (inname, 0666); ! 291: #ifndef MAIL_USE_MMDF ! 292: unlink (lockname); ! 293: #endif /* not MAIL_USE_MMDF */ ! 294: #endif /* not MAIL_USE_FLOCK */ ! 295: exit (0); ! 296: } ! 297: ! 298: /* Print error message and exit. */ ! 299: ! 300: fatal (s1, s2) ! 301: char *s1, *s2; ! 302: { ! 303: if (delete_lockname) ! 304: unlink (delete_lockname); ! 305: error (s1, s2); ! 306: exit (1); ! 307: } ! 308: ! 309: /* Print error message. `s1' is printf control string, `s2' is arg for it. */ ! 310: ! 311: error (s1, s2, s3) ! 312: char *s1, *s2, *s3; ! 313: { ! 314: printf ("movemail: "); ! 315: printf (s1, s2, s3); ! 316: printf ("\n"); ! 317: } ! 318: ! 319: pfatal_with_name (name) ! 320: char *name; ! 321: { ! 322: extern int errno, sys_nerr; ! 323: extern char *sys_errlist[]; ! 324: char *s; ! 325: ! 326: if (errno < sys_nerr) ! 327: s = concat ("", sys_errlist[errno], " for %s"); ! 328: else ! 329: s = "cannot open %s"; ! 330: fatal (s, name); ! 331: } ! 332: ! 333: pfatal_and_delete (name) ! 334: char *name; ! 335: { ! 336: extern int errno, sys_nerr; ! 337: extern char *sys_errlist[]; ! 338: char *s; ! 339: ! 340: if (errno < sys_nerr) ! 341: s = concat ("", sys_errlist[errno], " for %s"); ! 342: else ! 343: s = "cannot open %s"; ! 344: ! 345: unlink (name); ! 346: fatal (s, name); ! 347: } ! 348: ! 349: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ ! 350: ! 351: char * ! 352: concat (s1, s2, s3) ! 353: char *s1, *s2, *s3; ! 354: { ! 355: int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); ! 356: char *result = (char *) xmalloc (len1 + len2 + len3 + 1); ! 357: ! 358: strcpy (result, s1); ! 359: strcpy (result + len1, s2); ! 360: strcpy (result + len1 + len2, s3); ! 361: *(result + len1 + len2 + len3) = 0; ! 362: ! 363: return result; ! 364: } ! 365: ! 366: /* Like malloc but get fatal error if memory is exhausted. */ ! 367: ! 368: int ! 369: xmalloc (size) ! 370: int size; ! 371: { ! 372: int result = malloc (size); ! 373: if (!result) ! 374: fatal ("virtual memory exhausted", 0); ! 375: return result; ! 376: } ! 377: ! 378: /* This is the guts of the interface to the Post Office Protocol. */ ! 379: ! 380: #ifdef MAIL_USE_POP ! 381: ! 382: #include <sys/socket.h> ! 383: #include <netinet/in.h> ! 384: #include <netdb.h> ! 385: #include <stdio.h> ! 386: #include <pwd.h> ! 387: ! 388: #ifdef USG ! 389: #include <fcntl.h> ! 390: /* Cancel substitutions made by config.h for Emacs. */ ! 391: #undef open ! 392: #undef read ! 393: #undef write ! 394: #undef close ! 395: #endif /* USG */ ! 396: ! 397: #define NOTOK (-1) ! 398: #define OK 0 ! 399: #define DONE 1 ! 400: ! 401: char *progname; ! 402: FILE *sfi; ! 403: FILE *sfo; ! 404: char Errmsg[80]; ! 405: ! 406: static int debug = 0; ! 407: ! 408: char *get_errmsg (); ! 409: char *getenv (); ! 410: int mbx_write (); ! 411: ! 412: popmail (user, outfile) ! 413: char *user; ! 414: char *outfile; ! 415: { ! 416: char *host; ! 417: int nmsgs, nbytes; ! 418: char response[128]; ! 419: register int i; ! 420: int mbfi; ! 421: FILE *mbf; ! 422: struct passwd *pw = (struct passwd *) getpwuid (getuid ()); ! 423: if (pw == NULL) ! 424: fatal ("cannot determine user name"); ! 425: ! 426: host = getenv ("MAILHOST"); ! 427: if (host == NULL) ! 428: { ! 429: fatal ("no MAILHOST defined"); ! 430: } ! 431: ! 432: if (pop_init (host) == NOTOK) ! 433: { ! 434: fatal (Errmsg); ! 435: } ! 436: ! 437: if (getline (response, sizeof response, sfi) != OK) ! 438: { ! 439: fatal (response); ! 440: } ! 441: ! 442: if (pop_command ("USER %s", user) == NOTOK ! 443: || pop_command ("RPOP %s", pw->pw_name) == NOTOK) ! 444: { ! 445: pop_command ("QUIT"); ! 446: fatal (Errmsg); ! 447: } ! 448: ! 449: if (pop_stat (&nmsgs, &nbytes) == NOTOK) ! 450: { ! 451: pop_command ("QUIT"); ! 452: fatal (Errmsg); ! 453: } ! 454: ! 455: if (!nmsgs) ! 456: { ! 457: pop_command ("QUIT"); ! 458: return 0; ! 459: } ! 460: ! 461: mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); ! 462: if (mbfi < 0) ! 463: { ! 464: pop_command ("QUIT"); ! 465: pfatal_and_delete (outfile); ! 466: } ! 467: fchown (mbfi, getuid (), -1); ! 468: ! 469: if ((mbf = fdopen (mbfi, "w")) == NULL) ! 470: { ! 471: pop_command ("QUIT"); ! 472: pfatal_and_delete (outfile); ! 473: } ! 474: ! 475: for (i = 1; i <= nmsgs; i++) ! 476: { ! 477: mbx_delimit_begin (mbf); ! 478: if (pop_retr (i, mbx_write, mbf) != OK) ! 479: { ! 480: pop_command ("QUIT"); ! 481: close (mbfi); ! 482: unlink (outfile); ! 483: fatal (Errmsg); ! 484: } ! 485: mbx_delimit_end (mbf); ! 486: fflush (mbf); ! 487: } ! 488: ! 489: if (fsync (mbfi) < 0) ! 490: { ! 491: pop_command ("QUIT"); ! 492: pfatal_and_delete (outfile); ! 493: } ! 494: ! 495: if (close (mbfi) == -1) ! 496: { ! 497: pop_command ("QUIT"); ! 498: pfatal_and_delete (outfile); ! 499: } ! 500: ! 501: for (i = 1; i <= nmsgs; i++) ! 502: { ! 503: if (pop_command ("DELE %d", i) == NOTOK) ! 504: { ! 505: /* Better to ignore this failure. */ ! 506: } ! 507: } ! 508: ! 509: pop_command ("QUIT"); ! 510: return (0); ! 511: } ! 512: ! 513: pop_init (host) ! 514: char *host; ! 515: { ! 516: register struct hostent *hp; ! 517: register struct servent *sp; ! 518: int lport = IPPORT_RESERVED - 1; ! 519: struct sockaddr_in sin; ! 520: register int s; ! 521: ! 522: hp = gethostbyname (host); ! 523: if (hp == NULL) ! 524: { ! 525: sprintf (Errmsg, "MAILHOST unknown: %s", host); ! 526: return NOTOK; ! 527: } ! 528: ! 529: sp = getservbyname ("pop", "tcp"); ! 530: if (sp == 0) ! 531: { ! 532: strcpy (Errmsg, "tcp/pop: unknown service"); ! 533: return NOTOK; ! 534: } ! 535: ! 536: sin.sin_family = hp->h_addrtype; ! 537: bcopy (hp->h_addr, (char *)&sin.sin_addr, hp->h_length); ! 538: sin.sin_port = sp->s_port; ! 539: s = rresvport (&lport); ! 540: if (s < 0) ! 541: { ! 542: sprintf (Errmsg, "error creating socket: %s", get_errmsg ()); ! 543: return NOTOK; ! 544: } ! 545: ! 546: if (connect (s, (char *)&sin, sizeof sin) < 0) ! 547: { ! 548: sprintf (Errmsg, "error during connect: %s", get_errmsg ()); ! 549: close (s); ! 550: return NOTOK; ! 551: } ! 552: ! 553: sfi = fdopen (s, "r"); ! 554: sfo = fdopen (s, "w"); ! 555: if (sfi == NULL || sfo == NULL) ! 556: { ! 557: sprintf (Errmsg, "error in fdopen: %s", get_errmsg ()); ! 558: close (s); ! 559: return NOTOK; ! 560: } ! 561: ! 562: return OK; ! 563: } ! 564: ! 565: pop_command (fmt, a, b, c, d) ! 566: char *fmt; ! 567: { ! 568: char buf[128]; ! 569: char errmsg[64]; ! 570: ! 571: sprintf (buf, fmt, a, b, c, d); ! 572: ! 573: if (debug) fprintf (stderr, "---> %s\n", buf); ! 574: if (putline (buf, Errmsg, sfo) == NOTOK) return NOTOK; ! 575: ! 576: if (getline (buf, sizeof buf, sfi) != OK) ! 577: { ! 578: strcpy (Errmsg, buf); ! 579: return NOTOK; ! 580: } ! 581: ! 582: if (debug) ! 583: fprintf (stderr, "<--- %s\n", buf); ! 584: if (*buf != '+') ! 585: { ! 586: strcpy (Errmsg, buf); ! 587: return NOTOK; ! 588: } ! 589: else ! 590: { ! 591: return OK; ! 592: } ! 593: } ! 594: ! 595: ! 596: pop_stat (nmsgs, nbytes) ! 597: int *nmsgs, *nbytes; ! 598: { ! 599: char buf[128]; ! 600: ! 601: if (debug) ! 602: fprintf (stderr, "---> STAT\n"); ! 603: if (putline ("STAT", Errmsg, sfo) == NOTOK) ! 604: return NOTOK; ! 605: ! 606: if (getline (buf, sizeof buf, sfi) != OK) ! 607: { ! 608: strcpy (Errmsg, buf); ! 609: return NOTOK; ! 610: } ! 611: ! 612: if (debug) fprintf (stderr, "<--- %s\n", buf); ! 613: if (*buf != '+') ! 614: { ! 615: strcpy (Errmsg, buf); ! 616: return NOTOK; ! 617: } ! 618: else ! 619: { ! 620: sscanf (buf, "+OK %d %d", nmsgs, nbytes); ! 621: return OK; ! 622: } ! 623: } ! 624: ! 625: pop_retr (msgno, action, arg) ! 626: int (*action)(); ! 627: { ! 628: char buf[128]; ! 629: ! 630: sprintf (buf, "RETR %d", msgno); ! 631: if (debug) fprintf (stderr, "%s\n", buf); ! 632: if (putline (buf, Errmsg, sfo) == NOTOK) return NOTOK; ! 633: ! 634: if (getline (buf, sizeof buf, sfi) != OK) ! 635: { ! 636: strcpy (Errmsg, buf); ! 637: return NOTOK; ! 638: } ! 639: ! 640: while (1) ! 641: { ! 642: switch (multiline (buf, sizeof buf, sfi)) ! 643: { ! 644: case OK: ! 645: (*action)(buf, arg); ! 646: break; ! 647: case DONE: ! 648: return OK; ! 649: case NOTOK: ! 650: strcpy (Errmsg, buf); ! 651: return NOTOK; ! 652: } ! 653: } ! 654: } ! 655: ! 656: getline (buf, n, f) ! 657: char *buf; ! 658: register int n; ! 659: FILE *f; ! 660: { ! 661: register char *p; ! 662: int c; ! 663: ! 664: p = buf; ! 665: while (--n > 0 && (c = fgetc (f)) != EOF) ! 666: if ((*p++ = c) == '\n') break; ! 667: ! 668: if (ferror (f)) ! 669: { ! 670: strcpy (buf, "error on connection"); ! 671: return NOTOK; ! 672: } ! 673: ! 674: if (c == EOF && p == buf) ! 675: { ! 676: strcpy (buf, "connection closed by foreign host"); ! 677: return DONE; ! 678: } ! 679: ! 680: *p = NULL; ! 681: if (*--p == '\n') *p = NULL; ! 682: if (*--p == '\r') *p = NULL; ! 683: return OK; ! 684: } ! 685: ! 686: multiline (buf, n, f) ! 687: char *buf; ! 688: register int n; ! 689: FILE *f; ! 690: { ! 691: if (getline (buf, n, f) != OK) ! 692: return NOTOK; ! 693: if (*buf == '.') ! 694: { ! 695: if (*(buf+1) == NULL) ! 696: return DONE; ! 697: else ! 698: strcpy (buf, buf+1); ! 699: } ! 700: return OK; ! 701: } ! 702: ! 703: char * ! 704: get_errmsg () ! 705: { ! 706: extern int errno, sys_nerr; ! 707: extern char *sys_errlist[]; ! 708: char *s; ! 709: ! 710: if (errno < sys_nerr) ! 711: s = sys_errlist[errno]; ! 712: else ! 713: s = "unknown error"; ! 714: return (s); ! 715: } ! 716: ! 717: putline (buf, err, f) ! 718: char *buf; ! 719: char *err; ! 720: FILE *f; ! 721: { ! 722: fprintf (f, "%s\r\n", buf); ! 723: fflush (f); ! 724: if (ferror (f)) ! 725: { ! 726: strcpy (err, "lost connection"); ! 727: return NOTOK; ! 728: } ! 729: return OK; ! 730: } ! 731: ! 732: mbx_write (line, mbf) ! 733: char *line; ! 734: FILE *mbf; ! 735: { ! 736: fputs (line, mbf); ! 737: fputc (0x0a, mbf); ! 738: } ! 739: ! 740: mbx_delimit_begin (mbf) ! 741: FILE *mbf; ! 742: { ! 743: fputs ("\f\n0, unseen,,\n", mbf); ! 744: } ! 745: ! 746: mbx_delimit_end (mbf) ! 747: FILE *mbf; ! 748: { ! 749: putc ('\037', mbf); ! 750: } ! 751: ! 752: #endif /* MAIL_USE_POP */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.