X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/aaf70a50e13231ba06df17d79147ac0d7fed6d91..afaab789:/uip/inc.c?ds=inline diff --git a/uip/inc.c b/uip/inc.c index f1bafd90..b44e89e5 100644 --- a/uip/inc.c +++ b/uip/inc.c @@ -1,6 +1,4 @@ - -/* - * inc.c -- incorporate messages from a maildrop into a folder +/* inc.c -- incorporate messages from a maildrop into a folder * * This code is Copyright (c) 2002, by the authors of nmh. See the * COPYRIGHT file in the root directory of the nmh distribution for @@ -42,11 +40,14 @@ #include #include #include +#include "../sbr/lock_file.h" +#include "../sbr/m_maildir.h" +#include "../sbr/m_mktemp.h" -#ifndef CYRUS_SASL -# define SASLminc(a) (a) +#ifndef TLS_SUPPORT +# define TLSminc(a) (a) #else -# define SASLminc(a) 0 +# define TLSminc(a) 0 #endif #define INC_SWITCHES \ @@ -69,11 +70,15 @@ X("width columns", 0, WIDTHSW) \ X("version", 0, VERSIONSW) \ X("help", 0, HELPSW) \ - X("snoop", -5, SNOOPSW) \ - X("sasl", SASLminc(5), SASLSW) \ - X("nosasl", SASLminc(3), NOSASLSW) \ - X("saslmech", SASLminc(5), SASLMECHSW) \ - X("authservice", SASLminc(0), AUTHSERVICESW) \ + X("snoop", 0, SNOOPSW) \ + X("sasl", 0, SASLSW) \ + X("nosasl", 0, NOSASLSW) \ + X("saslmech", 0, SASLMECHSW) \ + X("initialtls", TLSminc(-10), INITTLSSW) \ + X("notls", TLSminc(-5), NOTLSSW) \ + X("certverify", TLSminc(-10), CERTVERSW) \ + X("nocertverify", TLSminc(-12), NOCERTVERSW) \ + X("authservice", 0, AUTHSERVICESW) \ X("proxy command", 0, PROXYSW) \ #define X(sw, minchars, id) id, @@ -174,19 +179,20 @@ maildir_srt(const void *va, const void *vb) const struct Maildir_entry *a = va, *b = vb; if (a->mtime > b->mtime) return 1; - else if (a->mtime < b->mtime) + if (a->mtime < b->mtime) return -1; - else - return 0; + return 0; } int main (int argc, char **argv) { - int chgflag = 1, trnflag = 1; - int noisy = 1, width = -1; + bool chgflag; + int trnflag = 1; + bool noisy; + int width = -1; int hghnum = 0, msgnum = 0; - int sasl = 0; + 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; char *format = NULL, *form = NULL; @@ -211,7 +217,7 @@ main (int argc, char **argv) if (nmh_init(argv[0], 1)) { return 1; } - mts_init (invo_name); + mts_init (); arguments = getarguments (invo_name, argc, argv, 1); argp = arguments; @@ -231,16 +237,18 @@ main (int argc, char **argv) if (pophost && *pophost) host = pophost; + sasl = tls = false; + chgflag = noisy = noverify = true; while ((cp = *argp++)) { if (*cp == '-') { switch (smatch (++cp, switches)) { - case AMBIGSW: + case AMBIGSW: ambigsw (cp, switches); done (1); - case UNKWNSW: + case UNKWNSW: adios (NULL, "-%s unknown", cp); - case HELPSW: + case HELPSW: snprintf (buf, sizeof(buf), "%s [+folder] [switches]", invo_name); print_help (buf, switches, 1); done (0); @@ -248,20 +256,20 @@ main (int argc, char **argv) print_version(invo_name); done (0); - case AUDSW: + case AUDSW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); audfile = getcpy (m_maildir (cp)); continue; - case NAUDSW: + case NAUDSW: audfile = NULL; continue; - case CHGSW: - chgflag++; + case CHGSW: + chgflag = true; continue; - case NCHGSW: - chgflag = 0; + case NCHGSW: + chgflag = false; continue; /* @@ -271,14 +279,14 @@ main (int argc, char **argv) * 1 by default (truncating is default) * 0 if -notruncate is given */ - case TRNCSW: + case TRNCSW: trnflag = 2; continue; - case NTRNCSW: + case NTRNCSW: trnflag = 0; continue; - case FILESW: + case FILESW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); from = path (cp, TFILE); @@ -291,25 +299,25 @@ main (int argc, char **argv) trnflag = 0; continue; - case SILSW: - noisy = 0; + case SILSW: + noisy = false; continue; - case NSILSW: - noisy++; + case NSILSW: + noisy = true; continue; - case FORMSW: + case FORMSW: if (!(form = *argp++) || *form == '-') adios (NULL, "missing argument to %s", argp[-2]); format = NULL; continue; - case FMTSW: + case FMTSW: if (!(format = *argp++) || *format == '-') adios (NULL, "missing argument to %s", argp[-2]); form = NULL; continue; - case WIDTHSW: + case WIDTHSW: if (!(cp = *argp++) || *cp == '-') adios (NULL, "missing argument to %s", argp[-2]); width = atoi (cp); @@ -343,10 +351,10 @@ main (int argc, char **argv) continue; case SASLSW: - sasl++; + sasl = true; continue; case NOSASLSW: - sasl = 0; + sasl = false; continue; case SASLMECHSW: @@ -354,6 +362,22 @@ main (int argc, char **argv) adios (NULL, "missing argument to %s", argp[-2]); continue; + case INITTLSSW: + tls = true; + continue; + + case NOTLSSW: + tls = false; + continue; + + case CERTVERSW: + noverify = false; + continue; + + case NOCERTVERSW: + noverify = true; + continue; + case AUTHSERVICESW: #ifdef OAUTH_SUPPORT if (!(auth_svc = *argp++) || *auth_svc == '-') @@ -385,7 +409,7 @@ main (int argc, char **argv) if (host && !*host) host = NULL; - /* guarantee dropping group priveleges; we might not have done so earlier */ + /* guarantee dropping group privileges; we might not have done so earlier */ DROPGROUPPRIVS(); /* @@ -403,25 +427,29 @@ main (int argc, char **argv) * a POP server? */ if (inc_type == INC_POP) { - struct nmh_creds creds = { 0, 0, 0 }; + int tlsflag = 0; if (auth_svc == NULL) { if (saslmech && ! strcasecmp(saslmech, "xoauth2")) { adios (NULL, "must specify -authservice with -saslmech xoauth2"); } - nmh_get_credentials (host, user, sasl, &creds); } else { if (user == NULL) { adios (NULL, "must specify -user with -saslmech xoauth2"); } - creds.user = user; } + if (tls) + tlsflag |= P_INITTLS; + + if (noverify) + tlsflag |= P_NOVERIFY; + /* * initialize POP connection */ - if (pop_init (host, port, creds.user, creds.password, proxy, snoop, - sasl, saslmech, auth_svc) == NOTOK) + if (pop_init (host, port, user, proxy, snoop, sasl, saslmech, + tlsflag, auth_svc) == NOTOK) adios (NULL, "%s", response); /* Check if there are any messages */ @@ -501,9 +529,7 @@ main (int argc, char **argv) qsort (Maildir, num_maildir_entries, sizeof(*Maildir), maildir_srt); } - if ((cp = strdup(newmail)) == (char *)0) - adios (NULL, "error allocating memory to copy newmail"); - + cp = mh_xstrdup(newmail); newmail = cp; } @@ -516,9 +542,7 @@ main (int argc, char **argv) if (!folder) folder = getfolder (0); maildir = m_maildir (folder); - - if ((maildir_copy = strdup(maildir)) == (char *)0) - adios (maildir, "error allocating memory to copy maildir"); + maildir_copy = mh_xstrdup(maildir); if (!folder_exists(maildir)) { /* If the folder doesn't exist, and we're given the -silent flag, @@ -568,7 +592,7 @@ go_to_it: if (audfile) { int i; if ((i = stat (audfile, &st)) == NOTOK) - advise (NULL, "Creating Receive-Audit: %s", audfile); + inform("Creating Receive-Audit: %s", audfile); if ((aud = fopen (audfile, "a")) == NULL) adios (audfile, "unable to append to"); else if (i == NOTOK) @@ -605,7 +629,7 @@ go_to_it: if (errno != ENOENT) adios (packfile, "error on file"); cp = concat ("Create file \"", packfile, "\"? ", NULL); - if (noisy && !getanswer (cp)) + if (noisy && !read_yes_or_no_if_tty (cp)) done (1); free (cp); } @@ -624,12 +648,14 @@ go_to_it: msgnum++; if (packfile) { + size_t len; + fseek (pf, 0L, SEEK_CUR); pos = ftell (pf); size = 0; - if (fwrite (mmdlm1, 1, strlen (mmdlm1), pf) < strlen (mmdlm1)) { + len = strlen(mmdlm1); + if (fwrite(mmdlm1, 1, len, pf) < len) advise (mmdlm1, "fwrite"); - } start = ftell (pf); if (pop_retr (i, pop_pack) == NOTOK) @@ -641,7 +667,7 @@ go_to_it: adios (packfile, "write error on"); fseek (pf, start, SEEK_SET); } else { - cp = getcpy (m_name (msgnum)); + cp = mh_xstrdup(m_name (msgnum)); if ((pf = fopen (cp, "w+")) == NULL) adios (cp, "unable to write"); chmod (cp, m_gmprot ()); @@ -657,7 +683,7 @@ go_to_it: switch (incerr = scan (pf, msgnum, 0, nfs, width, packfile ? 0 : msgnum == mp->hghmsg + 1 && chgflag, 1, NULL, stop - start, noisy, &scanl)) { - case SCNEOF: + case SCNEOF: printf ("%*d empty\n", DMAXFOLDER, msgnum); break; @@ -665,15 +691,15 @@ go_to_it: trnflag = 0; noisy++; /* advise (cp, "unable to read"); already advised */ - /* fall thru */ + /* FALLTHRU */ case SCNERR: - case SCNNUM: + case SCNNUM: break; - case SCNMSG: + case SCNMSG: case SCNENC: - default: + default: if (aud) fputs (charstring_buffer (scanl), aud); if (noisy) @@ -683,10 +709,12 @@ go_to_it: charstring_free (scanl); if (packfile) { + size_t len; + fseek (pf, stop, SEEK_SET); - if (fwrite (mmdlm2, 1, strlen (mmdlm2), pf) < strlen (mmdlm1)) { + len = strlen(mmdlm2); + if (fwrite(mmdlm2, 1, len, pf) < len) advise (mmdlm2, "fwrite"); - } if (fflush (pf) || ferror (pf)) { int e = errno; pop_quit (); @@ -733,21 +761,21 @@ go_to_it: msgnum == hghnum && chgflag, 1, NULL, 0L, noisy, &scanl)) { case SCNFAT: - case SCNEOF: + case SCNEOF: break; case SCNERR: if (aud) fputs ("inc aborted!\n", aud); - advise (NULL, "aborted!"); /* doesn't clean up locks! */ + inform("aborted!"); /* doesn't clean up locks! */ break; - case SCNNUM: - advise (NULL, "BUG in %s, number out of range", invo_name); + case SCNNUM: + inform("BUG in %s, number out of range", invo_name); break; - default: - advise (NULL, "BUG in %s, scan() botch (%d)", invo_name, incerr); + default: + inform("BUG in %s, scan() botch (%d)", invo_name, incerr); break; case SCNMSG: @@ -757,7 +785,7 @@ go_to_it: */ (void)snprintf(b, sizeof (b), "%s/%d", maildir_copy, msgnum + 1); - (void)ext_hook("add-hook", b, (char *)0); + (void)ext_hook("add-hook", b, NULL); if (aud) fputs (charstring_buffer (scanl), aud); @@ -786,7 +814,7 @@ go_to_it: msgnum++; sp = Maildir[i].filename; - cp = getcpy (m_name (msgnum)); + cp = mh_xstrdup(m_name (msgnum)); pf = NULL; if (!trnflag || link(sp, cp) == -1) { static char buf[65536]; @@ -807,7 +835,7 @@ go_to_it: } fclose (sf); sf = NULL; - } + } if (pf == NULL && (pf = fopen (cp, "r")) == NULL) adios (cp, "not available"); chmod (cp, m_gmprot ()); @@ -816,7 +844,7 @@ go_to_it: switch (incerr = scan (pf, msgnum, 0, nfs, width, msgnum == mp->hghmsg + 1 && chgflag, 1, NULL, stop - start, noisy, &scanl)) { - case SCNEOF: + case SCNEOF: printf ("%*d empty\n", DMAXFOLDER, msgnum); break; @@ -824,21 +852,21 @@ go_to_it: trnflag = 0; noisy++; /* advise (cp, "unable to read"); already advised */ - /* fall thru */ + /* FALLTHRU */ case SCNERR: - case SCNNUM: + case SCNNUM: break; - case SCNMSG: + case SCNMSG: case SCNENC: - default: + default: /* * Run the external program hook on the message. */ (void)snprintf(b, sizeof (b), "%s/%d", maildir_copy, msgnum + 1); - (void)ext_hook("add-hook", b, (char *)0); + (void)ext_hook("add-hook", b, NULL); if (aud) fputs (charstring_buffer (scanl), aud); @@ -894,7 +922,7 @@ go_to_it: if (inc_type == INC_FILE && Maildir == NULL) { if (trnflag) { if (stat (newmail, &st) != NOTOK && s1.st_mtime != st.st_mtime) - advise (NULL, "new messages have arrived!\007"); + inform("new messages have arrived!\007"); else { int newfd; if ((newfd = creat (newmail, 0600)) != NOTOK) @@ -910,7 +938,7 @@ go_to_it: } if (msgnum == hghnum) { - admonish (NULL, "no messages incorporated"); + inform("no messages incorporated, continuing..."); } else { /* * Lock the sequence file now, and loop to set the right flags @@ -923,7 +951,7 @@ go_to_it: context_replace (pfolder, folder); /* update current folder */ if ((mp2 = folder_read(folder, 1)) == NULL) { - admonish(NULL, "Unable to reread folder %s", folder); + inform("Unable to reread folder %s, continuing...", folder); goto skip; } @@ -933,7 +961,7 @@ go_to_it: if (msgnum >= mp2->hghoff && !(mp2 = folder_realloc (mp2, mp2->lowoff, msgnum + 1))) { - advise (NULL, "unable to reallocate folder storage"); + inform("unable to reallocate folder storage"); goto skip; } @@ -977,7 +1005,7 @@ skip: } -static void +static void NORETURN inc_done (int status) { done = exit;