static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order) { int nmsgs, nbytes; register int i; int mbfi; FILE *mbf; char *getenv (const char *); popserver server; int start, end, increment; char *user, *hostname; user = mailbox; if ((hostname = strchr (mailbox, ':'))) *hostname++ = '\0'; server = pop_open (hostname, user, password, POP_NO_GETPASS); if (! server) { error ("Error connecting to POP server: %s", pop_error, 0); return EXIT_FAILURE; } if (pop_stat (server, &nmsgs, &nbytes)) { error ("Error getting message count from POP server: %s", pop_error, 0); return EXIT_FAILURE; } if (!nmsgs) { pop_close (server); return EXIT_SUCCESS; } mbfi = open (outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); if (mbfi < 0) { pop_close (server); error ("Error in open: %s, %s", strerror (errno), outfile); return EXIT_FAILURE; } if (fchown (mbfi, getuid (), -1) != 0) { int fchown_errno = errno; struct stat st; if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ()) { pop_close (server); error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile); return EXIT_FAILURE; } } if ((mbf = fdopen (mbfi, "wb")) == NULL) { pop_close (server); error ("Error in fdopen: %s", strerror (errno), 0); close (mbfi); unlink (outfile); return EXIT_FAILURE; } if (reverse_order) { start = nmsgs; end = 1; increment = -1; } else { start = 1; end = nmsgs; increment = 1; } for (i = start; i * increment <= end * increment; i += increment) { mbx_delimit_begin (mbf); if (pop_retr (server, i, mbf) != OK) { error ("%s", Errmsg, 0); close (mbfi); return EXIT_FAILURE; } mbx_delimit_end (mbf); fflush (mbf); if (ferror (mbf)) { error ("Error in fflush: %s", strerror (errno), 0); pop_close (server); close (mbfi); return EXIT_FAILURE; } } /* On AFS, a call to write only modifies the file in the local * workstation's AFS cache. The changes are not written to the server * until a call to fsync or close is made. Users with AFS home * directories have lost mail when over quota because these checks were * not made in previous versions of movemail. */ #ifdef BSD_SYSTEM if (fsync (mbfi) < 0) { error ("Error in fsync: %s", strerror (errno), 0); return EXIT_FAILURE; } #endif if (close (mbfi) == -1) { error ("Error in close: %s", strerror (errno), 0); return EXIT_FAILURE; } if (! preserve) for (i = 1; i <= nmsgs; i++) { if (pop_delete (server, i)) { error ("Error from POP server: %s", pop_error, 0); pop_close (server); return EXIT_FAILURE; } } if (pop_quit (server)) { error ("Error from POP server: %s", pop_error, 0); return EXIT_FAILURE; } return EXIT_SUCCESS; }
static int popmail (char *mailbox, char *outfile, int preserve, char *password, int reverse_order) { int nmsgs, nbytes; register int i; int mbfi; FILE *mbf; popserver server; int start, end, increment; char *user, *hostname; user = mailbox; if ((hostname = strchr (mailbox, ':'))) *hostname++ = '\0'; server = pop_open (hostname, user, password, POP_NO_GETPASS); if (! server) { error ("Error connecting to POP server: %s", pop_error, 0); return EXIT_FAILURE; } if (pop_stat (server, &nmsgs, &nbytes)) { error ("Error getting message count from POP server: %s", pop_error, 0); return EXIT_FAILURE; } if (!nmsgs) { pop_close (server); return EXIT_SUCCESS; } mbfi = open (outfile, O_WRONLY | O_BINARY | O_CREAT | O_EXCL, 0666); if (mbfi < 0) { pop_close (server); error ("Error in open: %s, %s", strerror (errno), outfile); return EXIT_FAILURE; } if (fchown (mbfi, getuid (), -1) != 0) { int fchown_errno = errno; struct stat st; if (fstat (mbfi, &st) != 0 || st.st_uid != getuid ()) { pop_close (server); error ("Error in fchown: %s, %s", strerror (fchown_errno), outfile); return EXIT_FAILURE; } } if ((mbf = fdopen (mbfi, "wb")) == NULL) { pop_close (server); error ("Error in fdopen: %s", strerror (errno), 0); close (mbfi); unlink (outfile); return EXIT_FAILURE; } if (reverse_order) { start = nmsgs; end = 1; increment = -1; } else { start = 1; end = nmsgs; increment = 1; } for (i = start; i * increment <= end * increment; i += increment) { mbx_delimit_begin (mbf); if (pop_retr (server, i, mbf) != OK) { error ("%s", Errmsg, 0); close (mbfi); return EXIT_FAILURE; } mbx_delimit_end (mbf); fflush (mbf); if (ferror (mbf)) { error ("Error in fflush: %s", strerror (errno), 0); pop_close (server); close (mbfi); return EXIT_FAILURE; } } if (fsync (mbfi) != 0 && errno != EINVAL) { error ("Error in fsync: %s", strerror (errno), 0); close (mbfi); return EXIT_FAILURE; } if (close (mbfi) != 0) { error ("Error in close: %s", strerror (errno), 0); return EXIT_FAILURE; } if (! preserve) for (i = 1; i <= nmsgs; i++) { if (pop_delete (server, i)) { error ("Error from POP server: %s", pop_error, 0); pop_close (server); return EXIT_FAILURE; } } if (pop_quit (server)) { error ("Error from POP server: %s", pop_error, 0); return EXIT_FAILURE; } return EXIT_SUCCESS; }