X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/337b4e616e8f53ba06285b1645e1df9918ed5c16..b0aa8cdb1c264e42d4931ca24968689c73381278:/uip/inc.c diff --git a/uip/inc.c b/uip/inc.c index 1ea618db..069e3ce5 100644 --- a/uip/inc.c +++ b/uip/inc.c @@ -8,7 +8,13 @@ */ #ifdef MAILGROUP -/* Revised: Sat Apr 14 17:08:17 PDT 1990 (marvit@hplabs) +/* + * Thu Feb 12 21:00 CST 2015 Marcin Cieslak + * Replaced setgid() calls with setegid() so that it works with dot + * locking on FreeBSD. setegid() should be supported on modern POSIX + * systems. + * + * Revised: Sat Apr 14 17:08:17 PDT 1990 (marvit@hplabs) * Added hpux hacks to set and reset gid to be "mail" as needed. The reset * is necessary so inc'ed mail is the group of the inc'er, rather than * "mail". We setgid to egid only when [un]locking the mail file. This @@ -37,10 +43,10 @@ #include #include -#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 \ @@ -63,10 +69,13 @@ X("width columns", 0, WIDTHSW) \ X("version", 0, VERSIONSW) \ X("help", 0, HELPSW) \ - X("snoop", -5, SNOOPSW) \ - X("sasl", SASLminc(-4), SASLSW) \ - X("nosasl", SASLminc(-6), NOSASLSW) \ - X("saslmech", SASLminc(-8), SASLMECHSW) \ + 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("authservice", 0, AUTHSERVICESW) \ X("proxy command", 0, PROXYSW) \ #define X(sw, minchars, id) id, @@ -127,10 +136,16 @@ static FILE *pf = NULL; * For setting and returning to "mail" gid */ #ifdef MAILGROUP -static int return_gid; +static gid_t return_gid; #define TRYDROPGROUPPRIVS() DROPGROUPPRIVS() -#define DROPGROUPPRIVS() setgid(getgid()) -#define GETGROUPPRIVS() setgid(return_gid) +#define DROPGROUPPRIVS() \ + if (setegid(getgid()) != 0) { \ + adios ("setegid", "unable to restore group to %ld", (long) getgid()); \ + } +#define GETGROUPPRIVS() \ + if (setegid(return_gid) != 0) { \ + adios ("setegid", "unable to set group to %ld", (long) return_gid); \ + } #define SAVEGROUPPRIVS() return_gid = getegid() #else /* define *GROUPPRIVS() as null; this avoids having lots of "#ifdef MAILGROUP"s */ @@ -161,10 +176,9 @@ 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 @@ -173,12 +187,12 @@ main (int argc, char **argv) int chgflag = 1, trnflag = 1; int noisy = 1, width = -1; int hghnum = 0, msgnum = 0; - int sasl = 0; + int sasl = 0, tls = 0; 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; char *host = NULL, *port = NULL, *user = NULL, *proxy = NULL; - char *audfile = NULL, *from = NULL, *saslmech = NULL; + char *audfile = NULL, *from = NULL, *saslmech = NULL, *auth_svc = NULL; char buf[BUFSIZ], **argp, *nfs, **arguments; struct msgs *mp = NULL; struct stat st, s1; @@ -188,7 +202,6 @@ main (int argc, char **argv) int nmsgs, nbytes; char *MAILHOST_env_variable; - done=inc_done; /* absolutely the first thing we do is save our privileges, @@ -199,7 +212,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; @@ -222,13 +235,13 @@ main (int argc, char **argv) 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); @@ -236,19 +249,19 @@ 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: + case CHGSW: chgflag++; continue; - case NCHGSW: + case NCHGSW: chgflag = 0; continue; @@ -259,14 +272,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); @@ -279,25 +292,25 @@ main (int argc, char **argv) trnflag = 0; continue; - case SILSW: + case SILSW: noisy = 0; continue; - case NSILSW: + case NSILSW: noisy++; 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); @@ -341,6 +354,24 @@ main (int argc, char **argv) if (!(saslmech = *argp++) || *saslmech == '-') adios (NULL, "missing argument to %s", argp[-2]); continue; + + case INITTLSSW: + tls++; + continue; + + case NOTLSSW: + tls = 0; + continue; + + case AUTHSERVICESW: +#ifdef OAUTH_SUPPORT + if (!(auth_svc = *argp++) || *auth_svc == '-') + adios (NULL, "missing argument to %s", argp[-2]); +#else + adios (NULL, "not built with OAuth support"); +#endif + continue; + case PROXYSW: if (!(proxy = *argp++) || *proxy == '-') adios (NULL, "missing argument to %s", argp[-2]); @@ -381,14 +412,21 @@ main (int argc, char **argv) * a POP server? */ if (inc_type == INC_POP) { - struct nmh_creds creds = { 0, 0, 0 }; + if (auth_svc == NULL) { + if (saslmech && ! strcasecmp(saslmech, "xoauth2")) { + adios (NULL, "must specify -authservice with -saslmech xoauth2"); + } + } else { + if (user == NULL) { + adios (NULL, "must specify -user with -saslmech xoauth2"); + } + } /* * initialize POP connection */ - nmh_get_credentials (host, user, sasl, &creds); - if (pop_init (host, port, creds.user, creds.password, proxy, snoop, - sasl, saslmech) == NOTOK) + if (pop_init (host, port, user, proxy, snoop, sasl, saslmech, + tls, auth_svc) == NOTOK) adios (NULL, "%s", response); /* Check if there are any messages */ @@ -468,7 +506,7 @@ main (int argc, char **argv) qsort (Maildir, num_maildir_entries, sizeof(*Maildir), maildir_srt); } - if ((cp = strdup(newmail)) == (char *)0) + if ((cp = strdup(newmail)) == NULL) adios (NULL, "error allocating memory to copy newmail"); newmail = cp; @@ -484,7 +522,7 @@ main (int argc, char **argv) folder = getfolder (0); maildir = m_maildir (folder); - if ((maildir_copy = strdup(maildir)) == (char *)0) + if ((maildir_copy = strdup(maildir)) == NULL) adios (maildir, "error allocating memory to copy maildir"); if (!folder_exists(maildir)) { @@ -572,7 +610,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); } @@ -591,10 +629,14 @@ go_to_it: msgnum++; if (packfile) { + size_t len; + fseek (pf, 0L, SEEK_CUR); pos = ftell (pf); size = 0; - fwrite (mmdlm1, 1, strlen (mmdlm1), pf); + len = strlen(mmdlm1); + if (fwrite(mmdlm1, 1, len, pf) < len) + advise (mmdlm1, "fwrite"); start = ftell (pf); if (pop_retr (i, pop_pack) == NOTOK) @@ -606,7 +648,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 ()); @@ -622,7 +664,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; @@ -633,12 +675,12 @@ go_to_it: /* fall thru */ case SCNERR: - case SCNNUM: + case SCNNUM: break; - case SCNMSG: + case SCNMSG: case SCNENC: - default: + default: if (aud) fputs (charstring_buffer (scanl), aud); if (noisy) @@ -648,8 +690,12 @@ go_to_it: charstring_free (scanl); if (packfile) { + size_t len; + fseek (pf, stop, SEEK_SET); - fwrite (mmdlm2, 1, strlen (mmdlm2), pf); + len = strlen(mmdlm2); + if (fwrite(mmdlm2, 1, len, pf) < len) + advise (mmdlm2, "fwrite"); if (fflush (pf) || ferror (pf)) { int e = errno; pop_quit (); @@ -696,7 +742,7 @@ go_to_it: msgnum == hghnum && chgflag, 1, NULL, 0L, noisy, &scanl)) { case SCNFAT: - case SCNEOF: + case SCNEOF: break; case SCNERR: @@ -705,11 +751,11 @@ go_to_it: advise (NULL, "aborted!"); /* doesn't clean up locks! */ break; - case SCNNUM: + case SCNNUM: advise (NULL, "BUG in %s, number out of range", invo_name); break; - default: + default: advise (NULL, "BUG in %s, scan() botch (%d)", invo_name, incerr); break; @@ -720,7 +766,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); @@ -749,7 +795,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]; @@ -770,7 +816,7 @@ go_to_it: } fclose (sf); sf = NULL; - } + } if (pf == NULL && (pf = fopen (cp, "r")) == NULL) adios (cp, "not available"); chmod (cp, m_gmprot ()); @@ -779,7 +825,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; @@ -790,18 +836,18 @@ go_to_it: /* fall thru */ 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); @@ -943,6 +989,7 @@ skip: static void inc_done (int status) { + done = exit; if (packfile && pd != NOTOK) mbx_close (packfile, pd); if (locked)