3 * msgchk.c -- check for mail
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
16 # include <h/popsbr.h>
20 # define POPminc(a) (a)
26 # define SASLminc(a) (a)
28 # define SASLminc(a) 0
31 static struct swit switches[] = {
39 { "nonotify type", 0 },
41 { "host hostname", POPminc (-4) },
43 { "user username", POPminc (-4) },
45 { "port name/number", POPminc(-4) },
53 { "sasl", SASLminc(-4) },
55 { "saslmech", SASLminc(-5) },
57 { "proxy command", POPminc(-5) },
62 * Maximum numbers of users we can check (plus
63 * one for the NULL vector at the end).
69 #endif /* Use NT_NONE to prevent warning from gcc -Wunused-macros. */
72 #define NT_ALL (NT_MAIL | NT_NMAI)
77 #define UUCPOK (UUCPOLD | UUCPNEW)
80 #define MMDFOK (MMDFOLD | MMDFNEW)
86 static int donote (char *, int);
87 static int checkmail (char *, char *, int, int, int);
90 static int remotemail (char *, char *, char *, char *, int, int, int, int,
96 main (int argc, char **argv)
98 int datesw = 1, notifysw = NT_ALL;
99 int status = 0, sasl = 0;
100 int snoop = 0, vecp = 0;
101 char *cp, *host = NULL, *port = NULL, *user, *proxy = NULL;
102 char buf[BUFSIZ], *saslmech = NULL;
103 char **argp, **arguments, *vec[MAXVEC];
107 struct hes_postoffice *po;
112 setlocale(LC_ALL, "");
114 invo_name = r1bindex (argv[0], '/');
116 /* read user profile/context */
119 mts_init (invo_name);
120 user = getusername();
122 arguments = getarguments (invo_name, argc, argv, 1);
126 if ((cp = getenv ("MHPOPDEBUG")) && *cp)
130 while ((cp = *argp++)) {
132 switch (smatch (++cp, switches)) {
134 ambigsw (cp, switches);
137 adios (NULL, "-%s unknown", cp);
140 snprintf (buf, sizeof(buf), "%s [switches] [users ...]",
142 print_help (buf, switches, 1);
145 print_version(invo_name);
156 if (!(cp = *argp++) || *cp == '-')
157 adios (NULL, "missing argument to %s", argp[-2]);
158 notifysw |= donote (cp, 1);
161 if (!(cp = *argp++) || *cp == '-')
162 adios (NULL, "missing argument to %s", argp[-2]);
163 notifysw &= ~donote (cp, 0);
167 if (!(host = *argp++) || *host == '-')
168 adios (NULL, "missing argument to %s", argp[-2]);
172 if (!(port = *argp++) || *port == '-')
173 adios (NULL, "missing argument to %s", argp[-2]);
177 if (!(cp = *argp++) || *cp == '-')
178 adios (NULL, "missing argument to %s", argp[-2]);
179 if (vecp >= MAXVEC-1)
180 adios (NULL, "you can only check %d users at a time", MAXVEC-1);
194 if (!(saslmech = *argp++) || *saslmech == '-')
195 adios (NULL, "missing argument to %s", argp[-2]);
199 if (!(proxy = *argp++) || *proxy == '-')
200 adios (NULL, "missing argument to %s", argp[-2]);
204 if (vecp >= MAXVEC-1)
205 adios (NULL, "you can only check %d users at a time", MAXVEC-1);
212 * If -host is not specified by user
214 if (!host || !*host) {
216 * If "pophost" is specified in mts.conf,
217 * use it as default value.
219 if (pophost && *pophost)
232 status = remotemail (host, port, user, proxy, notifysw, 1,
233 snoop, sasl, saslmech);
235 for (vecp = 0; vec[vecp]; vecp++)
236 status += remotemail (host, port, vec[vecp], proxy, notifysw, 0,
237 snoop, sasl, saslmech);
245 /* Not sure this check makes sense... */
246 if (!geteuid() || NULL == (home = getenv("HOME"))) {
247 pw = getpwnam (user);
249 adios (NULL, "unable to get information about user");
252 status = checkmail (user, home, datesw, notifysw, 1);
254 for (vecp = 0; vec[vecp]; vecp++) {
255 if ((pw = getpwnam (vec[vecp])))
256 status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
258 advise (NULL, "no such user as %s", vec[vecp]);
270 static struct swit ntswitches[] = {
282 donote (char *cp, int ntflag)
284 switch (smatch (cp, ntswitches)) {
286 ambigsw (cp, ntswitches);
289 adios (NULL, "-%snotify %s unknown", ntflag ? "" : "no", cp);
299 return 0; /* Before 1999-07-15, garbage was returned if control got here. */
304 checkmail (char *user, char *home, int datesw, int notifysw, int personal)
310 snprintf (buffer, sizeof(buffer), "%s/%s", mmdfldir[0] ? mmdfldir : home, mmdflfil[0] ? mmdflfil : user);
313 st.st_atime = st.st_mtime = 0;
315 mf = (stat (buffer, &st) == NOTOK || st.st_size == 0) ? NONEOK
316 : st.st_atime <= st.st_mtime ? MMDFNEW : MMDFOLD;
318 if ((mf & UUCPOK) || (mf & MMDFOK)) {
319 if (notifysw & NT_MAIL) {
320 printf (personal ? "You have " : "%s has ", user);
322 printf ("%s old-style bell", mf & UUCPOLD ? "old" : "new");
323 if ((mf & UUCPOK) && (mf & MMDFOK))
326 printf ("%s%s", mf & MMDFOLD ? "old" : "new",
327 mf & UUCPOK ? " Internet" : "");
328 printf (" mail waiting");
335 if (notifysw & NT_NMAI)
336 printf (personal ? "You don't %s%s" : "%s doesn't %s",
337 personal ? "" : user, "have any mail waiting");
345 if (datesw && st.st_atime)
346 printf ("; last read on %s", dtime (&st.st_atime, 1));
355 extern char response[];
358 remotemail (char *host, char *port, char *user, char *proxy, int notifysw,
359 int personal, int snoop, int sasl, char *saslmech)
361 int nmsgs, nbytes, status;
365 user = getusername ();
367 pass = getusername ();
369 ruserpass (host, &user, &pass);
371 /* open the POP connection */
372 if (pop_init (host, port, user, pass, proxy, snoop, sasl, saslmech) == NOTOK
373 || pop_stat (&nmsgs, &nbytes) == NOTOK /* check for messages */
374 || pop_quit () == NOTOK) { /* quit POP connection */
375 advise (NULL, "%s", response);
380 if (notifysw & NT_MAIL) {
381 printf (personal ? "You have " : "%s has ", user);
382 printf ("%d message%s (%d bytes)",
383 nmsgs, nmsgs != 1 ? "s" : "", nbytes);
390 if (notifysw & NT_NMAI)
391 printf (personal ? "You don't %s%s" : "%s doesn't %s",
392 personal ? "" : user, "have any mail waiting");
398 printf (" on %s\n", host);