Fix support of scripts in w32font.c (Bug#19993)
[emacs.git] / lib-src / movemail.c
blob1618a6980e984c5b287688a53b47c24d07a32159
1 /* movemail foo bar -- move file foo to file bar,
2 locking file foo the way /bin/mail respects.
4 Copyright (C) 1986, 1992-1994, 1996, 1999, 2001-2015 Free Software
5 Foundation, Inc.
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
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
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
27 system's own conventions. It is not a choice that is up to you.
29 So, if your system uses lock files rather than flock, then the only way
30 you can get proper operation is to enable movemail to write lockfiles there.
31 This means you must either give that directory access modes
32 that permit everyone to write lockfiles in it, or you must make movemail
33 a setuid or setgid program. */
36 * Modified January, 1986 by Michael R. Gretzinger (Project Athena)
38 * Added POP (Post Office Protocol) service. When compiled -DMAIL_USE_POP
39 * movemail will accept input filename arguments of the form
40 * "po:username". This will cause movemail to open a connection to
41 * a pop server running on $MAILHOST (environment variable). Movemail
42 * must be setuid to root in order to work with POP.
44 * New module: popmail.c
45 * Modified routines:
46 * main - added code within #ifdef MAIL_USE_POP; added setuid (getuid ())
47 * after POP code.
48 * New routines in movemail.c:
49 * get_errmsg - return pointer to system error message
51 * Modified August, 1993 by Jonathan Kamens (OpenVision Technologies)
53 * Move all of the POP code into a separate file, "pop.c".
54 * Use strerror instead of get_errmsg.
58 #include <config.h>
59 #include <sys/types.h>
60 #include <sys/stat.h>
61 #include <sys/file.h>
62 #include <stdbool.h>
63 #include <stdio.h>
64 #include <errno.h>
65 #include <time.h>
67 #include <getopt.h>
68 #include <unistd.h>
69 #include <fcntl.h>
70 #include <signal.h>
71 #include <string.h>
72 #include "syswait.h"
73 #ifdef MAIL_USE_POP
74 #include "pop.h"
75 #endif
77 #ifdef MSDOS
78 #undef access
79 #endif /* MSDOS */
81 #ifdef WINDOWSNT
82 #include "ntlib.h"
83 #undef access
84 #undef unlink
85 #define fork() 0
86 #define waitpid(child, var, flags) (*(var) = 0)
87 /* Unfortunately, Samba doesn't seem to properly lock Unix files even
88 though the locking call succeeds (and indeed blocks local access from
89 other NT programs). If you have direct file access using an NFS
90 client or something other than Samba, the locking call might work
91 properly - make sure it does before you enable this!
93 [18-Feb-97 andrewi] I now believe my comment above to be incorrect,
94 since it was based on a misunderstanding of how locking calls are
95 implemented and used on Unix. */
96 //#define DISABLE_DIRECT_ACCESS
98 #include <fcntl.h>
99 #endif /* WINDOWSNT */
101 #ifdef WINDOWSNT
102 #include <sys/locking.h>
103 #endif
105 /* If your system uses the `flock' or `lockf' system call for mail locking,
106 define MAIL_USE_SYSTEM_LOCK. If your system type should always define
107 MAIL_USE_LOCKF or MAIL_USE_FLOCK but configure does not do this,
108 please make a bug report. */
110 #ifdef MAIL_USE_LOCKF
111 #define MAIL_USE_SYSTEM_LOCK
112 #endif
114 #ifdef MAIL_USE_FLOCK
115 #define MAIL_USE_SYSTEM_LOCK
116 #endif
118 #ifdef MAIL_USE_MMDF
119 extern int lk_open (), lk_close ();
120 #endif
122 #if !defined (MAIL_USE_SYSTEM_LOCK) && !defined (MAIL_USE_MMDF) && \
123 (defined (HAVE_LIBMAIL) || defined (HAVE_LIBLOCKFILE)) && \
124 defined (HAVE_MAILLOCK_H)
125 #include <maillock.h>
126 /* We can't use maillock unless we know what directory system mail
127 files appear in. */
128 #ifdef MAILDIR
129 #define MAIL_USE_MAILLOCK
130 static char *mail_spool_name (char *);
131 #endif
132 #endif
134 static _Noreturn void fatal (const char *s1, const char *s2, const char *s3);
135 static void error (const char *s1, const char *s2, const char *s3);
136 static _Noreturn void pfatal_with_name (char *name);
137 static _Noreturn void pfatal_and_delete (char *name);
138 #ifdef MAIL_USE_POP
139 static int popmail (char *, char *, bool, char *, bool);
140 static bool pop_retr (popserver, int, FILE *);
141 static bool mbx_write (char *, int, FILE *);
142 static bool mbx_delimit_begin (FILE *);
143 static bool mbx_delimit_end (FILE *);
144 #endif
146 #if (defined MAIL_USE_MAILLOCK \
147 || (!defined DISABLE_DIRECT_ACCESS && !defined MAIL_USE_MMDF \
148 && !defined MAIL_USE_SYSTEM_LOCK))
149 /* Like malloc but get fatal error if memory is exhausted. */
151 static void *
152 xmalloc (size_t size)
154 void *result = malloc (size);
155 if (!result)
156 fatal ("virtual memory exhausted", 0, 0);
157 return result;
159 #endif
161 /* Nonzero means this is name of a lock file to delete on fatal error. */
162 static char *delete_lockname;
165 main (int argc, char **argv)
167 char *inname, *outname;
168 int indesc, outdesc;
169 ssize_t nread;
170 int wait_status;
171 int c;
172 bool preserve_mail = false;
174 #ifndef MAIL_USE_SYSTEM_LOCK
175 struct stat st;
176 int tem;
177 char *tempname;
178 size_t inname_len, inname_dirlen;
179 int desc;
180 #endif /* not MAIL_USE_SYSTEM_LOCK */
182 char *spool_name = 0;
184 #ifdef MAIL_USE_POP
185 bool pop_reverse_order = false;
186 # define ARGSTR "pr"
187 #else /* ! MAIL_USE_POP */
188 # define ARGSTR "p"
189 #endif /* MAIL_USE_POP */
191 uid_t real_gid = getgid ();
192 uid_t priv_gid = getegid ();
194 delete_lockname = 0;
196 while (0 <= (c = getopt (argc, argv, ARGSTR)))
198 switch (c) {
199 #ifdef MAIL_USE_POP
200 case 'r':
201 pop_reverse_order = true;
202 break;
203 #endif
204 case 'p':
205 preserve_mail = true;
206 break;
207 default:
208 return EXIT_FAILURE;
212 if (
213 #ifdef MAIL_USE_POP
214 (argc - optind < 2) || (argc - optind > 3)
215 #else
216 (argc - optind != 2)
217 #endif
220 #ifdef MAIL_USE_POP
221 fprintf (stderr, "Usage: movemail [-p] [-r] inbox destfile%s\n",
222 " [POP-password]");
223 #else
224 fprintf (stderr, "Usage: movemail [-p] inbox destfile%s\n", "");
225 #endif
226 return EXIT_FAILURE;
229 inname = argv[optind];
230 outname = argv[optind+1];
232 #ifdef MAIL_USE_MMDF
233 mmdf_init (argv[0]);
234 #endif
236 if (*outname == 0)
237 fatal ("Destination file name is empty", 0, 0);
239 #ifdef MAIL_USE_POP
240 if (!strncmp (inname, "po:", 3))
242 int status;
244 status = popmail (inname + 3, outname, preserve_mail,
245 (argc - optind == 3) ? argv[optind+2] : NULL,
246 pop_reverse_order);
247 return status;
250 if (setuid (getuid ()) < 0)
251 fatal ("Failed to drop privileges", 0, 0);
253 #endif /* MAIL_USE_POP */
255 #ifndef DISABLE_DIRECT_ACCESS
257 char *lockname = 0;
259 #ifndef MAIL_USE_MMDF
260 #ifndef MAIL_USE_SYSTEM_LOCK
261 #ifdef MAIL_USE_MAILLOCK
262 spool_name = mail_spool_name (inname);
263 #endif
264 if (! spool_name)
266 /* Use a lock file named after our first argument with .lock appended:
267 If it exists, the mail file is locked. */
268 /* Note: this locking mechanism is *required* by the mailer
269 (on systems which use it) to prevent loss of mail.
271 On systems that use a lock file, extracting the mail without locking
272 WILL occasionally cause loss of mail due to timing errors!
274 So, if creation of the lock file fails due to access
275 permission on the mail spool directory, you simply MUST
276 change the permission and/or make movemail a setgid program
277 so it can create lock files properly.
279 You might also wish to verify that your system is one which
280 uses lock files for this purpose. Some systems use other methods. */
282 inname_len = strlen (inname);
283 lockname = xmalloc (inname_len + sizeof ".lock");
284 strcpy (lockname, inname);
285 strcpy (lockname + inname_len, ".lock");
286 for (inname_dirlen = inname_len;
287 inname_dirlen && !IS_DIRECTORY_SEP (inname[inname_dirlen - 1]);
288 inname_dirlen--)
289 continue;
290 tempname = xmalloc (inname_dirlen + sizeof "EXXXXXX");
292 while (true)
294 /* Create the lock file, but not under the lock file name. */
295 /* Give up if cannot do that. */
297 memcpy (tempname, inname, inname_dirlen);
298 strcpy (tempname + inname_dirlen, "EXXXXXX");
299 desc = mkostemp (tempname, O_BINARY);
300 if (desc < 0)
302 int mkostemp_errno = errno;
303 error ("error while creating what would become the lock file",
304 0, 0);
305 errno = mkostemp_errno;
306 pfatal_with_name (tempname);
308 close (desc);
310 tem = link (tempname, lockname);
312 if (tem < 0 && errno != EEXIST)
313 pfatal_with_name (lockname);
315 unlink (tempname);
316 if (tem >= 0)
317 break;
318 sleep (1);
320 /* If lock file is five minutes old, unlock it.
321 Five minutes should be good enough to cope with crashes
322 and wedgitude, and long enough to avoid being fooled
323 by time differences between machines. */
324 if (stat (lockname, &st) >= 0)
326 time_t now = time (0);
327 if (st.st_ctime < now - 300)
329 unlink (lockname);
330 lockname = 0;
335 delete_lockname = lockname;
337 #endif /* not MAIL_USE_SYSTEM_LOCK */
338 #endif /* not MAIL_USE_MMDF */
340 #ifdef SIGCHLD
341 signal (SIGCHLD, SIG_DFL);
342 #endif
344 pid_t child = fork ();
345 if (child < 0)
346 fatal ("Error in fork; %s", strerror (errno), 0);
348 if (child == 0)
350 int lockcount = 0;
351 int status = 0;
352 #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK)
353 time_t touched_lock IF_LINT (= 0);
354 #endif
356 if (setuid (getuid ()) < 0 || setregid (-1, real_gid) < 0)
357 fatal ("Failed to drop privileges", 0, 0);
359 #ifndef MAIL_USE_MMDF
360 #ifdef MAIL_USE_SYSTEM_LOCK
361 indesc = open (inname, O_RDWR | O_BINARY);
362 #else /* if not MAIL_USE_SYSTEM_LOCK */
363 indesc = open (inname, O_RDONLY | O_BINARY);
364 #endif /* not MAIL_USE_SYSTEM_LOCK */
365 #else /* MAIL_USE_MMDF */
366 indesc = lk_open (inname, O_RDONLY | O_BINARY, 0, 0, 10);
367 #endif /* MAIL_USE_MMDF */
369 if (indesc < 0)
370 pfatal_with_name (inname);
372 /* Make sure the user can read the output file. */
373 umask (umask (0) & 0377);
375 outdesc = open (outname, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0666);
376 if (outdesc < 0)
377 pfatal_with_name (outname);
379 if (setregid (-1, priv_gid) < 0)
380 fatal ("Failed to regain privileges", 0, 0);
382 /* This label exists so we can retry locking
383 after a delay, if it got EAGAIN or EBUSY. */
384 retry_lock:
386 /* Try to lock it. */
387 #ifdef MAIL_USE_MAILLOCK
388 if (spool_name)
390 /* The "-" is to make it a negative number if maillock returns
391 non-zero. */
392 status = - maillock (spool_name, 1);
393 #ifdef HAVE_TOUCHLOCK
394 touched_lock = time (0);
395 #endif
396 lockcount = 5;
398 else
399 #endif /* MAIL_USE_MAILLOCK */
401 #ifdef MAIL_USE_SYSTEM_LOCK
402 #ifdef MAIL_USE_LOCKF
403 status = lockf (indesc, F_LOCK, 0);
404 #else /* not MAIL_USE_LOCKF */
405 #ifdef WINDOWSNT
406 status = locking (indesc, LK_RLCK, -1L);
407 #else
408 status = flock (indesc, LOCK_EX);
409 #endif
410 #endif /* not MAIL_USE_LOCKF */
411 #endif /* MAIL_USE_SYSTEM_LOCK */
414 /* If it fails, retry up to 5 times
415 for certain failure codes. */
416 if (status < 0)
418 if (++lockcount <= 5 && (errno == EAGAIN || errno == EBUSY))
420 sleep (1);
421 goto retry_lock;
424 pfatal_with_name (inname);
428 char buf[1024];
430 while (true)
432 nread = read (indesc, buf, sizeof buf);
433 if (nread < 0)
434 pfatal_with_name (inname);
435 if (nread != write (outdesc, buf, nread))
437 int saved_errno = errno;
438 unlink (outname);
439 errno = saved_errno;
440 pfatal_with_name (outname);
442 if (nread < sizeof buf)
443 break;
444 #if defined (MAIL_USE_MAILLOCK) && defined (HAVE_TOUCHLOCK)
445 if (spool_name)
447 time_t now = time (0);
448 if (now - touched_lock > 60)
450 touchlock ();
451 touched_lock = now;
454 #endif /* MAIL_USE_MAILLOCK */
458 if (fsync (outdesc) != 0 && errno != EINVAL)
459 pfatal_and_delete (outname);
461 /* Prevent symlink attacks truncating other users' mailboxes */
462 if (setregid (-1, real_gid) < 0)
463 fatal ("Failed to drop privileges", 0, 0);
465 /* Check to make sure no errors before we zap the inbox. */
466 if (close (outdesc) != 0)
467 pfatal_and_delete (outname);
469 #ifdef MAIL_USE_SYSTEM_LOCK
470 if (! preserve_mail)
472 if (ftruncate (indesc, 0) != 0)
473 pfatal_with_name (inname);
475 #endif /* MAIL_USE_SYSTEM_LOCK */
477 #ifdef MAIL_USE_MMDF
478 lk_close (indesc, 0, 0, 0);
479 #else
480 close (indesc);
481 #endif
483 #ifndef MAIL_USE_SYSTEM_LOCK
484 if (! preserve_mail)
486 /* Delete the input file; if we can't, at least get rid of its
487 contents. */
488 #ifdef MAIL_UNLINK_SPOOL
489 /* This is generally bad to do, because it destroys the permissions
490 that were set on the file. Better to just empty the file. */
491 if (unlink (inname) < 0 && errno != ENOENT)
492 #endif /* MAIL_UNLINK_SPOOL */
493 creat (inname, 0600);
495 #endif /* not MAIL_USE_SYSTEM_LOCK */
497 /* End of mailbox truncation */
498 if (setregid (-1, priv_gid) < 0)
499 fatal ("Failed to regain privileges", 0, 0);
501 #ifdef MAIL_USE_MAILLOCK
502 /* This has to occur in the child, i.e., in the process that
503 acquired the lock! */
504 if (spool_name)
505 mailunlock ();
506 #endif
507 return EXIT_SUCCESS;
510 if (waitpid (child, &wait_status, 0) < 0)
511 fatal ("Error in waitpid; %s", strerror (errno), 0);
512 if (!WIFEXITED (wait_status))
513 return EXIT_FAILURE;
514 else if (WEXITSTATUS (wait_status) != 0)
515 return WEXITSTATUS (wait_status);
517 if (lockname)
518 unlink (lockname);
520 #endif /* ! DISABLE_DIRECT_ACCESS */
522 return EXIT_SUCCESS;
525 #ifdef MAIL_USE_MAILLOCK
526 /* This function uses stat to confirm that the mail directory is
527 identical to the directory of the input file, rather than just
528 string-comparing the two paths, because one or both of them might
529 be symbolic links pointing to some other directory. */
530 static char *
531 mail_spool_name (char *inname)
533 struct stat stat1, stat2;
534 char *indir, *fname;
535 int status;
537 if (! (fname = strrchr (inname, '/')))
538 return NULL;
540 fname++;
542 if (stat (MAILDIR, &stat1) < 0)
543 return NULL;
545 indir = xmalloc (fname - inname + 1);
546 memcpy (indir, inname, fname - inname);
547 indir[fname-inname] = '\0';
550 status = stat (indir, &stat2);
552 free (indir);
554 if (status < 0)
555 return NULL;
557 if (stat1.st_dev == stat2.st_dev
558 && stat1.st_ino == stat2.st_ino)
559 return fname;
561 return NULL;
563 #endif /* MAIL_USE_MAILLOCK */
565 /* Print error message and exit. */
567 static void
568 fatal (const char *s1, const char *s2, const char *s3)
570 if (delete_lockname)
571 unlink (delete_lockname);
572 error (s1, s2, s3);
573 exit (EXIT_FAILURE);
576 /* Print error message. `s1' is printf control string, `s2' and `s3'
577 are args for it or null. */
579 static void
580 error (const char *s1, const char *s2, const char *s3)
582 fprintf (stderr, "movemail: ");
583 if (s3)
584 fprintf (stderr, s1, s2, s3);
585 else if (s2)
586 fprintf (stderr, s1, s2);
587 else
588 fprintf (stderr, "%s", s1);
589 fprintf (stderr, "\n");
592 static void
593 pfatal_with_name (char *name)
595 fatal ("%s for %s", strerror (errno), name);
598 static void
599 pfatal_and_delete (char *name)
601 char *s = strerror (errno);
602 unlink (name);
603 fatal ("%s for %s", s, name);
606 /* This is the guts of the interface to the Post Office Protocol. */
608 #ifdef MAIL_USE_POP
610 #ifndef WINDOWSNT
611 #include <sys/socket.h>
612 #include <netinet/in.h>
613 #include <netdb.h>
614 #else
615 #undef _WINSOCKAPI_
616 #include <winsock.h>
617 #endif
618 #include <pwd.h>
619 #include <string.h>
622 * The full valid syntax for a POP mailbox specification for movemail
623 * is "po:username:hostname". The ":hostname" is optional; if it is
624 * omitted, the MAILHOST environment variable will be consulted. Note
625 * that by the time popmail() is called the "po:" has been stripped
626 * off of the front of the mailbox name.
628 * If the mailbox is in the form "po:username:hostname", then it is
629 * modified by this function -- the second colon is replaced by a
630 * null.
632 * Return a value suitable for passing to `exit'.
635 static int
636 popmail (char *mailbox, char *outfile, bool preserve, char *password,
637 bool reverse_order)
639 int nmsgs, nbytes;
640 int i;
641 int mbfi;
642 FILE *mbf;
643 popserver server;
644 int start, end, increment;
645 char *user, *hostname;
647 user = mailbox;
648 if ((hostname = strchr (mailbox, ':')))
649 *hostname++ = '\0';
651 server = pop_open (hostname, user, password, POP_NO_GETPASS);
652 if (! server)
654 error ("Error connecting to POP server: %s", pop_error, 0);
655 return EXIT_FAILURE;
658 if (pop_stat (server, &nmsgs, &nbytes))
660 error ("Error getting message count from POP server: %s", pop_error, 0);
661 return EXIT_FAILURE;
664 if (!nmsgs)
666 pop_close (server);
667 return EXIT_SUCCESS;
670 mbfi = open (outfile, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0666);
671 if (mbfi < 0)
673 pop_close (server);
674 error ("Error in open: %s, %s", strerror (errno), outfile);
675 return EXIT_FAILURE;
678 if (fchown (mbfi, getuid (), -1) != 0)
680 int fchown_errno = errno;
681 struct stat st;
682 if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ())
684 pop_close (server);
685 error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile);
686 return EXIT_FAILURE;
690 mbf = fdopen (mbfi, "wb");
691 if (!mbf)
693 pop_close (server);
694 error ("Error in fdopen: %s", strerror (errno), 0);
695 close (mbfi);
696 unlink (outfile);
697 return EXIT_FAILURE;
700 if (reverse_order)
702 start = nmsgs;
703 end = 1;
704 increment = -1;
706 else
708 start = 1;
709 end = nmsgs;
710 increment = 1;
713 for (i = start; i * increment <= end * increment; i += increment)
714 if (! (mbx_delimit_begin (mbf)
715 && pop_retr (server, i, mbf)
716 && mbx_delimit_end (mbf)
717 && fflush (mbf) == 0))
719 if (errno)
720 error ("Error in POP retrieving: %s", strerror (errno), 0);
721 pop_close (server);
722 fclose (mbf);
723 return EXIT_FAILURE;
726 if (fsync (mbfi) != 0 && errno != EINVAL)
728 error ("Error in fsync: %s", strerror (errno), 0);
729 fclose (mbf);
730 return EXIT_FAILURE;
733 if (fclose (mbf) != 0)
735 error ("Error in fclose: %s", strerror (errno), 0);
736 return EXIT_FAILURE;
739 if (! preserve)
740 for (i = 1; i <= nmsgs; i++)
742 if (pop_delete (server, i))
744 error ("Error from POP server: %s", pop_error, 0);
745 pop_close (server);
746 return EXIT_FAILURE;
750 if (pop_quit (server))
752 error ("Error from POP server: %s", pop_error, 0);
753 return EXIT_FAILURE;
756 return EXIT_SUCCESS;
759 static bool
760 pop_retr (popserver server, int msgno, FILE *arg)
762 char *line;
763 int ret;
765 if (pop_retrieve_first (server, msgno, &line))
767 error ("Error from POP server: %s", pop_error, 0);
768 errno = 0;
769 return false;
772 while ((ret = pop_retrieve_next (server, &line)) >= 0)
774 if (! line)
775 break;
777 if (! mbx_write (line, ret, arg))
779 int write_errno = errno;
780 pop_close (server);
781 errno = write_errno;
782 return false;
786 if (ret)
788 error ("Error from POP server: %s", pop_error, 0);
789 errno = 0;
790 return false;
793 return true;
796 static bool
797 mbx_write (char *line, int len, FILE *mbf)
799 #ifdef MOVEMAIL_QUOTE_POP_FROM_LINES
800 /* Do this as a macro instead of using strcmp to save on execution time. */
801 # define IS_FROM_LINE(a) ((a[0] == 'F') \
802 && (a[1] == 'r') \
803 && (a[2] == 'o') \
804 && (a[3] == 'm') \
805 && (a[4] == ' '))
806 if (IS_FROM_LINE (line))
808 if (fputc ('>', mbf) < 0)
809 return false;
811 #endif
812 if (line[0] == '\037')
814 if (fputs ("^_", mbf) < 0)
815 return false;
816 line++;
817 len--;
819 return fwrite (line, 1, len, mbf) == len && 0 <= fputc ('\n', mbf);
822 static bool
823 mbx_delimit_begin (FILE *mbf)
825 time_t now = time (NULL);
826 struct tm *ltime = localtime (&now);
827 if (!ltime)
828 return false;
830 char fromline[100];
831 if (! strftime (fromline, sizeof fromline,
832 "From movemail %a %b %e %T %Y\n", ltime))
834 errno = EOVERFLOW;
835 return false;
837 return 0 <= fputs (fromline, mbf);
840 static bool
841 mbx_delimit_end (FILE *mbf)
843 return 0 <= putc ('\n', mbf);
846 #endif /* MAIL_USE_POP */