-
-/*
- * msgchk.c -- check for mail
+/* msgchk.c -- check for mail
*
* This code is Copyright (c) 2002, by the authors of nmh. See the
* COPYRIGHT file in the root directory of the nmh distribution for
* complete copyright information.
*/
-#include <h/mh.h>
-#include <h/mts.h>
-#include <h/tws.h>
+#include "h/mh.h"
+#include "sbr/print_version.h"
+#include "sbr/print_help.h"
+#include "sbr/error.h"
+#include "h/mts.h"
+#include "h/tws.h"
+#include "h/done.h"
+#include "h/utils.h"
#include <pwd.h>
-#include <h/popsbr.h>
+#include "h/popsbr.h"
#ifndef CYRUS_SASL
# define SASLminc(a) (a)
# define SASLminc(a) 0
#endif
+#ifndef TLS_SUPPORT
+# define TLSminc(a) (a)
+#else
+# define TLSminc(a) 0
+#endif
+
#define MSGCHK_SWITCHES \
X("date", 0, DATESW) \
X("nodate", 0, NDATESW) \
X("port name/number", 0, PORTSW) \
X("version", 0, VERSIONSW) \
X("help", 0, HELPSW) \
- X("snoop", -5, SNOOPSW) \
- X("sasl", SASLminc(-4), SASLSW) \
- X("saslmech", SASLminc(-5), SASLMECHSW) \
+ X("snoop", 0, SNOOPSW) \
+ X("sasl", SASLminc(4), SASLSW) \
+ X("nosasl", SASLminc(6), NOSASLSW) \
+ X("saslmech", SASLminc(5), SASLMECHSW) \
+ X("authservice", SASLminc(0), AUTHSERVICESW) \
+ X("initialtls", TLSminc(-10), INITTLSSW) \
+ X("notls", TLSminc(-5), NOTLSSW) \
+ X("certverify", TLSminc(-10), CERTVERSW) \
+ X("nocertverify", TLSminc(-12), NOCERTVERSW) \
X("proxy command", 0, PROXYSW) \
#define X(sw, minchars, id) id,
*/
#define MAXVEC 51
-#define NT_NONE 0x0
-#ifdef NT_NONE
-#endif /* Use NT_NONE to prevent warning from gcc -Wunused-macros. */
#define NT_MAIL 0x1
#define NT_NMAI 0x2
#define NT_ALL (NT_MAIL | NT_NMAI)
-#define NONEOK 0x0
-#define UUCPOLD 0x1
-#define UUCPNEW 0x2
-#define UUCPOK (UUCPOLD | UUCPNEW)
-#define MMDFOLD 0x4
-#define MMDFNEW 0x8
-#define MMDFOK (MMDFOLD | MMDFNEW)
-
/*
* static prototypes
*/
-static int donote (char *, int);
+static int donote (char *, int) PURE;
static int checkmail (char *, char *, int, int, int);
static int remotemail (char *, char *, char *, char *, int, int, int, int,
- char *);
+ char *, int, const char *);
int
main (int argc, char **argv)
{
- int datesw = 1, notifysw = NT_ALL;
- int status = 0, sasl = 0;
- int snoop = 0, vecp = 0;
+ bool datesw = true;
+ int notifysw = NT_ALL;
+ int status = 0;
+ bool sasl = false;
+ bool tls = false;
+ bool noverify = false;
+ bool snoop = false;
+ int vecp = 0;
char *cp, *host = NULL, *port = NULL, *user = NULL, *proxy = NULL;
- char buf[BUFSIZ], *saslmech = NULL;
+ char buf[BUFSIZ], *saslmech = NULL, *auth_svc = NULL;
char **argp, **arguments, *vec[MAXVEC];
struct passwd *pw;
-#ifdef LOCALE
- setlocale(LC_ALL, "");
-#endif
- invo_name = r1bindex (argv[0], '/');
+ if (nmh_init(argv[0], true, true)) { return 1; }
- /* read user profile/context */
- context_read();
-
- mts_init (invo_name);
+ mts_init ();
arguments = getarguments (invo_name, argc, argv, 1);
argp = arguments;
ambigsw (cp, switches);
done (1);
case UNKWNSW:
- adios (NULL, "-%s unknown", cp);
+ die("-%s unknown", cp);
case HELPSW:
snprintf (buf, sizeof(buf), "%s [switches] [users ...]",
done (0);
case DATESW:
- datesw++;
+ datesw = true;
continue;
case NDATESW:
- datesw = 0;
+ datesw = false;
continue;
case NOTESW:
if (!(cp = *argp++) || *cp == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
notifysw |= donote (cp, 1);
continue;
case NNOTESW:
if (!(cp = *argp++) || *cp == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
notifysw &= ~donote (cp, 0);
continue;
case HOSTSW:
if (!(host = *argp++) || *host == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case PORTSW:
if (!(port = *argp++) || *port == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
case USERSW:
if (!(cp = *argp++) || *cp == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
if (vecp >= MAXVEC-1)
- adios (NULL, "you can only check %d users at a time", MAXVEC-1);
- else
- user = vec[vecp++] = cp;
+ die("you can only check %d users at a time", MAXVEC-1);
+ user = vec[vecp++] = cp;
continue;
case SNOOPSW:
- snoop++;
+ snoop = true;
continue;
case SASLSW:
- sasl++;
+ sasl = true;
continue;
+ case NOSASLSW:
+ sasl = false;
+ continue;
+
case SASLMECHSW:
if (!(saslmech = *argp++) || *saslmech == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("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 == '-')
+ die("missing argument to %s", argp[-2]);
+#else
+ die("not built with OAuth support");
+#endif
continue;
case PROXYSW:
if (!(proxy = *argp++) || *proxy == '-')
- adios (NULL, "missing argument to %s", argp[-2]);
+ die("missing argument to %s", argp[-2]);
continue;
}
}
if (vecp >= MAXVEC-1)
- adios (NULL, "you can only check %d users at a time", MAXVEC-1);
- else
- vec[vecp++] = cp;
+ die("you can only check %d users at a time", MAXVEC-1);
+ vec[vecp++] = cp;
}
/*
vec[vecp] = NULL;
if (host) {
+ int tlsflag = 0;
+
+ if (tls)
+ tlsflag |= P_INITTLS;
+
+ if (noverify)
+ tlsflag |= P_NOVERIFY;
+
if (vecp == 0) {
status = remotemail (host, port, user, proxy, notifysw, 1,
- snoop, sasl, saslmech);
+ snoop, sasl, saslmech, tlsflag, auth_svc);
} else {
for (vecp = 0; vec[vecp]; vecp++)
status += remotemail (host, port, vec[vecp], proxy, notifysw, 0,
- snoop, sasl, saslmech);
+ snoop, sasl, saslmech, tlsflag, auth_svc);
}
} else {
if (user == NULL) user = getusername ();
if (!geteuid() || NULL == (home = getenv("HOME"))) {
pw = getpwnam (user);
if (pw == NULL)
- adios (NULL, "unable to get information about user");
+ die("unable to get information about user");
home = pw->pw_dir;
}
status = checkmail (user, home, datesw, notifysw, 1);
if ((pw = getpwnam (vec[vecp])))
status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
else
- advise (NULL, "no such user as %s", vec[vecp]);
+ inform("no such user as %s", vec[vecp]);
}
}
} /* host == NULL */
ambigsw (cp, ntswitches);
done (1);
case UNKWNSW:
- adios (NULL, "-%snotify %s unknown", ntflag ? "" : "no", cp);
+ die("-%snotify %s unknown", ntflag ? "" : "no", cp);
case NALLSW:
return NT_ALL;
static int
checkmail (char *user, char *home, int datesw, int notifysw, int personal)
{
- int mf, status;
char buffer[BUFSIZ];
+ snprintf(buffer, sizeof buffer, "%s/%s", *mmdfldir ? mmdfldir : home,
+ *mmdflfil ? mmdflfil : user);
+
struct stat st;
+ bool statok = stat(buffer, &st) != -1;
+ bool empty = !statok || st.st_size == 0;
- snprintf (buffer, sizeof(buffer), "%s/%s", mmdfldir[0] ? mmdfldir : home, mmdflfil[0] ? mmdflfil : user);
- if (datesw) {
- st.st_size = 0;
- st.st_atime = st.st_mtime = 0;
+ if ((empty && !(notifysw & NT_NMAI)) ||
+ (!empty && !(notifysw & NT_MAIL))) {
+ return empty;
}
- mf = (stat (buffer, &st) == NOTOK || st.st_size == 0) ? NONEOK
- : st.st_atime <= st.st_mtime ? MMDFNEW : MMDFOLD;
- if ((mf & UUCPOK) || (mf & MMDFOK)) {
- if (notifysw & NT_MAIL) {
- if (personal)
- printf ("You have ");
- else
- printf ("%s has ", user);
- if (mf & UUCPOK)
- printf ("%s old-style bell", mf & UUCPOLD ? "old" : "new");
- if ((mf & UUCPOK) && (mf & MMDFOK))
- printf (" and ");
- if (mf & MMDFOK)
- printf ("%s%s", mf & MMDFOLD ? "old" : "new",
- mf & UUCPOK ? " Internet" : "");
- printf (" mail waiting");
- } else {
- notifysw = 0;
- }
- status = 0;
- }
- else {
- if (notifysw & NT_NMAI)
- printf (personal ? "You don't %s%s" : "%s doesn't %s",
- personal ? "" : user, "have any mail waiting");
- else
- notifysw = 0;
-
- status = 1;
+ if (empty) {
+ if (personal) {
+ fputs("You don't have any mail waiting", stdout);
+ } else {
+ printf("%s doesn't have any mail waiting", user);
+ }
+ } else {
+ char *kind = st.st_mtime < st.st_atime ? "old" : "new";
+ if (personal) {
+ printf("You have %s mail waiting", kind);
+ } else {
+ printf("%s has %s mail waiting", user, kind);
+ }
}
- if (notifysw)
- if (datesw && st.st_atime)
- printf ("; last read on %s", dtime (&st.st_atime, 1));
- if (notifysw)
- printf ("\n");
+ if (datesw && statok && st.st_atime)
+ printf("; last read on %s", dtime(&st.st_atime, 1));
+ putchar('\n');
- return status;
+ return empty;
}
static int
remotemail (char *host, char *port, char *user, char *proxy, int notifysw,
- int personal, int snoop, int sasl, char *saslmech)
+ int personal, int snoop, int sasl, char *saslmech, int tls,
+ const char *auth_svc)
{
- int nmsgs, nbytes, status;
- struct nmh_creds creds = { 0, 0, 0 };
+ int nmsgs, nbytes;
+ bool status;
+
+ if (auth_svc == NULL) {
+ if (saslmech && ! strcasecmp(saslmech, "xoauth2")) {
+ die("must specify -authservice with -saslmech xoauth2");
+ }
+ } else {
+ if (user == NULL) {
+ die("must specify -user with -saslmech xoauth2");
+ }
+ }
/* open the 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
|| pop_stat (&nmsgs, &nbytes) == NOTOK /* check for messages */
|| pop_quit () == NOTOK) { /* quit POP connection */
- advise (NULL, "%s", response);
+ inform("%s", response);
return 1;
}
if (nmsgs) {
if (notifysw & NT_MAIL) {
if (personal)
- printf ("You have ");
+ fputs("You have ", stdout);
else
printf ("%s has ", user);
printf ("%d message%s (%d bytes)",
- nmsgs, nmsgs != 1 ? "s" : "", nbytes);
+ nmsgs, PLURALS(nmsgs), nbytes);
}
else
notifysw = 0;
- status = 0;
+ status = false;
} else {
if (notifysw & NT_NMAI)
printf (personal ? "You don't %s%s" : "%s doesn't %s",
personal ? "" : user, "have any mail waiting");
else
notifysw = 0;
- status = 1;
+ status = true;
}
if (notifysw)
printf (" on %s\n", host);