X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/6170b76c7d080efb5e980260d8fb7a33e0512f61..39a12997e2d7705a2760a1198932f23f4e590aab:/uip/inc.c diff --git a/uip/inc.c b/uip/inc.c index f3888394..ad454e10 100644 --- a/uip/inc.c +++ b/uip/inc.c @@ -93,7 +93,6 @@ DEFINE_SWITCH_ARRAY(INC, switches); #define INC_FILE 0 #define INC_POP 1 -static int inc_type; static struct Maildir_entry { char *filename; time_t mtime; @@ -101,12 +100,12 @@ static struct Maildir_entry { static int num_maildir_entries = 0; static int snoop = 0; -extern char response[]; - -static long start; -static long stop; +typedef struct { + FILE *mailout; + long written; +} pop_closure; -static FILE *pf = NULL; +extern char response[]; /* This is an attempt to simplify things by putting all the * privilege ops into macros. @@ -150,17 +149,18 @@ static gid_t return_gid; #endif /* not MAILGROUP */ /* these variables have to be globals so that done() can correctly clean up the lockfile */ -static int locked = 0; +static bool locked; static char *newmail; static FILE *in; /* * prototypes */ +static int maildir_srt(const void *va, const void *vb) PURE; static void inc_done(int) NORETURN; -static int pop_action(char *); +static int pop_action(void *closure, char *); -int +static int maildir_srt(const void *va, const void *vb) { const struct Maildir_entry *a = va, *b = vb; @@ -174,11 +174,13 @@ maildir_srt(const void *va, const void *vb) int main (int argc, char **argv) { + static int inc_type; bool chgflag; int trnflag = 1; bool noisy; int width = -1; int hghnum = 0, msgnum = 0; + FILE *pf = NULL; bool sasl, tls, noverify; int incerr = 0; /* <0 if inc hits an error which means it should not truncate mailspool */ char *cp, *maildir = NULL, *folder = NULL; @@ -375,8 +377,7 @@ main (int argc, char **argv) if (*cp == '+' || *cp == '@') { if (folder) adios (NULL, "only one folder at a time!"); - else - folder = pluspath (cp); + folder = pluspath (cp); } else { adios (NULL, "usage: %s [+folder] [switches]", invo_name); } @@ -391,21 +392,11 @@ main (int argc, char **argv) /* guarantee dropping group privileges; we might not have done so earlier */ DROPGROUPPRIVS(); - /* - * Where are we getting the new mail? - */ - if (from) - inc_type = INC_FILE; - else if (host) - inc_type = INC_POP; - else - inc_type = INC_FILE; + /* Source of mail; -from overrides any -host. */ + inc_type = host && !from ? INC_POP : INC_FILE; - /* - * Are we getting the mail from - * a POP server? - */ if (inc_type == INC_POP) { + /* Mail from a POP server. */ int tlsflag = 0; if (auth_svc == NULL) { @@ -439,14 +430,9 @@ main (int argc, char **argv) pop_quit(); adios (NULL, "no mail to incorporate"); } - } - - /* - * We will get the mail from a file - * (typically the standard maildrop) - */ - if (inc_type == INC_FILE) { + } else if (inc_type == INC_FILE) { + /* Mail from a spool file, or Maildir. */ if (from) newmail = from; else if ((newmail = getenv ("MAILDROP")) && *newmail) @@ -537,8 +523,10 @@ main (int argc, char **argv) adios (NULL, "unable to read folder %s", folder); if (inc_type == INC_FILE && Maildir == NULL) { + /* Mail from a spool file. */ + if (access (newmail, W_OK) != NOTOK) { - locked++; + locked = true; if (trnflag) { SIGNAL (SIGHUP, SIG_IGN); SIGNAL (SIGINT, SIG_IGN); @@ -568,7 +556,7 @@ main (int argc, char **argv) inform("Creating Receive-Audit: %s", audfile); if ((aud = fopen (audfile, "a")) == NULL) adios (audfile, "unable to append to"); - else if (i == NOTOK) + if (i == NOTOK) chmod (audfile, m_gmprot ()); if (from) @@ -595,7 +583,9 @@ main (int argc, char **argv) * Get the mail from a POP server */ if (inc_type == INC_POP) { + /* Mail from a POP server. */ int i; + pop_closure pc; hghnum = msgnum = mp->hghmsg; for (i = 1; i <= nmsgs; i++) { @@ -606,9 +596,10 @@ main (int argc, char **argv) if ((pf = fopen (cp, "w+")) == NULL) adios (cp, "unable to write"); chmod (cp, m_gmprot ()); - start = stop = 0L; - if (pop_retr (i, pop_action) == NOTOK) + pc.written = 0; + pc.mailout = pf; + if (pop_retr(i, pop_action, &pc) == NOTOK) adios (NULL, "%s", response); if (fflush (pf)) @@ -616,14 +607,14 @@ main (int argc, char **argv) fseek (pf, 0L, SEEK_SET); switch (incerr = scan (pf, msgnum, 0, nfs, width, msgnum == mp->hghmsg + 1 && chgflag, - 1, NULL, stop - start, noisy, &scanl)) { + 1, NULL, pc.written, noisy, &scanl)) { case SCNEOF: printf ("%*d empty\n", DMAXFOLDER, msgnum); break; case SCNFAT: trnflag = 0; - noisy++; + noisy = true; /* advise (cp, "unable to read"); already advised */ break; @@ -659,12 +650,10 @@ main (int argc, char **argv) if (pop_quit () == NOTOK) adios (NULL, "%s", response); - } - /* - * Get the mail from file (usually mail spool) - */ - if (inc_type == INC_FILE && Maildir == NULL) { + } else if (inc_type == INC_FILE && Maildir == NULL) { + /* Mail from a spool file. */ + scan_detect_mbox_style (in); /* the MAGIC invocation... */ hghnum = msgnum = mp->hghmsg; for (;;) { @@ -716,7 +705,9 @@ main (int argc, char **argv) */ break; } - } else if (inc_type == INC_FILE) { /* Maildir inbox to process */ + + } else { + /* Mail from Maildir. */ char *sp; FILE *sf; int i; @@ -757,14 +748,14 @@ main (int argc, char **argv) fseek (pf, 0L, SEEK_SET); switch (incerr = scan (pf, msgnum, 0, nfs, width, msgnum == mp->hghmsg + 1 && chgflag, - 1, NULL, stop - start, noisy, &scanl)) { + 1, NULL, 0, noisy, &scanl)) { case SCNEOF: printf ("%*d empty\n", DMAXFOLDER, msgnum); break; case SCNFAT: trnflag = 0; - noisy++; + noisy = true; /* advise (cp, "unable to read"); already advised */ break; @@ -827,10 +818,9 @@ main (int argc, char **argv) if (noisy) fflush (stdout); - /* - * truncate file we are incorporating from - */ if (inc_type == INC_FILE && Maildir == NULL) { + /* Mail from a spool file; truncate it. */ + if (trnflag) { if (stat (newmail, &st) != NOTOK && s1.st_mtime != st.st_mtime) inform("new messages have arrived!\007"); @@ -894,12 +884,11 @@ main (int argc, char **argv) seq_save(mp2); /* Save the sequence file */ folder_free(mp2); } -skip: - /* - * unlock the mail spool - */ +skip: if (inc_type == INC_FILE && Maildir == NULL) { + /* Mail from a spool file; unlock it. */ + if (locked) { GETGROUPPRIVS(); /* Be sure we can unlock mail file */ (void) lkfclosespool (in, newmail); in = NULL; @@ -929,9 +918,16 @@ inc_done (int status) } static int -pop_action (char *s) +pop_action(void *closure, char *s) { - fprintf (pf, "%s\n", s); - stop += strlen (s) + 1; - return 0; /* Is return value used? This was missing before 1999-07-15. */ + pop_closure *pc; + int n; + + pc = closure; + n = fprintf(pc->mailout, "%s\n", s); + if (n < 0) + return NOTOK; + pc->written += n; /* Count linefeed too. */ + + return OK; }