3 * msgchk.c -- check for mail
7 * This code is Copyright (c) 2002, by the authors of nmh. See the
8 * COPYRIGHT file in the root directory of the nmh distribution for
9 * complete copyright information.
18 # include <h/popsbr.h>
26 # define POPminc(a) (a)
32 # define RPOPminc(a) (a)
34 # define RPOPminc(a) 0
38 # define APOPminc(a) (a)
40 # define APOPminc(a) 0
44 # define KPOPminc(a) (a)
46 # define KPOPminc(a) 0
50 # define SASLminc(a) (a)
52 # define SASLminc(a) 0
55 static struct swit switches[] = {
63 { "nonotify type", 0 },
65 { "host hostname", POPminc (-4) },
67 { "user username", POPminc (-4) },
69 { "apop", APOPminc (-4) },
71 { "noapop", APOPminc (-6) },
73 { "rpop", RPOPminc (-4) },
75 { "norpop", RPOPminc (-6) },
83 { "kpop", KPOPminc (-4) },
85 { "sasl", SASLminc(-4) },
87 { "saslmech", SASLminc(-5) },
89 { "proxy command", POPminc(-5) },
94 * Maximum numbers of users we can check (plus
95 * one for the NULL vector at the end).
102 #define NT_ALL (NT_MAIL | NT_NMAI)
107 #define UUCPOK (UUCPOLD | UUCPNEW)
110 #define MMDFOK (MMDFOLD | MMDFNEW)
116 static int donote (char *, int);
117 static int checkmail (char *, char *, int, int, int);
120 static int remotemail (char *, char *, char *, int, int, int, int, int, int, char *);
125 main (int argc, char **argv)
127 int datesw = 1, notifysw = NT_ALL;
128 int rpop, status = 0;
129 int kpop = 0, sasl = 0;
130 int snoop = 0, vecp = 0;
132 char *cp, *host = NULL, *user, *proxy = NULL;
133 char buf[BUFSIZ], *saslmech = NULL;
134 char **argp, **arguments, *vec[MAXVEC];
138 struct hes_postoffice *po;
143 setlocale(LC_ALL, "");
145 invo_name = r1bindex (argv[0], '/');
147 /* read user profile/context */
150 mts_init (invo_name);
152 user = getusername();
154 arguments = getarguments (invo_name, argc, argv, 1);
158 if ((cp = getenv ("MHPOPDEBUG")) && *cp)
164 while ((cp = *argp++)) {
166 switch (smatch (++cp, switches)) {
168 ambigsw (cp, switches);
171 adios (NULL, "-%s unknown", cp);
174 snprintf (buf, sizeof(buf), "%s [switches] [users ...]",
176 print_help (buf, switches, 1);
179 print_version(invo_name);
190 if (!(cp = *argp++) || *cp == '-')
191 adios (NULL, "missing argument to %s", argp[-2]);
192 notifysw |= donote (cp, 1);
195 if (!(cp = *argp++) || *cp == '-')
196 adios (NULL, "missing argument to %s", argp[-2]);
197 notifysw &= ~donote (cp, 0);
201 if (!(host = *argp++) || *host == '-')
202 adios (NULL, "missing argument to %s", argp[-2]);
205 if (!(cp = *argp++) || *cp == '-')
206 adios (NULL, "missing argument to %s", argp[-2]);
207 if (vecp >= MAXVEC-1)
208 adios (NULL, "you can only check %d users at a time", MAXVEC-1);
240 if (!(saslmech = *argp++) || *saslmech == '-')
241 adios (NULL, "missing argument to %s", argp[-2]);
245 if (!(proxy = *argp++) || *proxy == '-')
246 adios (NULL, "missing argument to %s", argp[-2]);
250 if (vecp >= MAXVEC-1)
251 adios (NULL, "you can only check %d users at a time", MAXVEC-1);
258 * If -host is not specified by user
260 if (!host || !*host) {
264 * use MAILHOST environment variable if present,
266 * If that fails, use the default (if any)
267 * provided by mts.conf in mts_init()
269 if ((tmphost = getenv("MAILHOST")) != NULL)
271 else if ((po = hes_getmailhost(vecp ? vec[0] : user)) != NULL &&
272 strcmp(po->po_type, "POP") == 0)
273 pophost = po->po_host;
276 * If "pophost" is specified in mts.conf,
277 * use it as default value.
279 if (pophost && *pophost)
284 if (!host || rpop <= 0)
293 if ( strcmp( POPSERVICE, "kpop" ) == 0 ) {
297 status = remotemail (host, user, proxy, rpop, kpop, notifysw, 1,
298 snoop, sasl, saslmech);
300 for (vecp = 0; vec[vecp]; vecp++)
301 status += remotemail (host, vec[vecp], proxy, rpop, kpop,
302 notifysw, 0, snoop, sasl, saslmech);
310 /* Not sure this check makes sense... */
311 if (!geteuid() || NULL == (home = getenv("HOME"))) {
312 pw = getpwnam (user);
314 adios (NULL, "unable to get information about user");
317 status = checkmail (user, home, datesw, notifysw, 1);
319 for (vecp = 0; vec[vecp]; vecp++) {
320 if ((pw = getpwnam (vec[vecp])))
321 status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
323 advise (NULL, "no such user as %s", vec[vecp]);
335 static struct swit ntswitches[] = {
347 donote (char *cp, int ntflag)
349 switch (smatch (cp, ntswitches)) {
351 ambigsw (cp, ntswitches);
354 adios (NULL, "-%snotify %s unknown", ntflag ? "" : "no", cp);
364 return 0; /* Before 1999-07-15, garbage was returned if control got here. */
369 checkmail (char *user, char *home, int datesw, int notifysw, int personal)
375 snprintf (buffer, sizeof(buffer), "%s/%s", mmdfldir[0] ? mmdfldir : home, mmdflfil[0] ? mmdflfil : user);
378 st.st_atime = st.st_mtime = 0;
380 mf = (stat (buffer, &st) == NOTOK || st.st_size == 0) ? NONEOK
381 : st.st_atime <= st.st_mtime ? MMDFNEW : MMDFOLD;
383 if ((mf & UUCPOK) || (mf & MMDFOK)) {
384 if (notifysw & NT_MAIL) {
385 printf (personal ? "You have " : "%s has ", user);
387 printf ("%s old-style bell", mf & UUCPOLD ? "old" : "new");
388 if ((mf & UUCPOK) && (mf & MMDFOK))
391 printf ("%s%s", mf & MMDFOLD ? "old" : "new",
392 mf & UUCPOK ? " Internet" : "");
393 printf (" mail waiting");
400 if (notifysw & NT_NMAI)
401 printf (personal ? "You don't %s%s" : "%s doesn't %s",
402 personal ? "" : user, "have any mail waiting");
410 if (datesw && st.st_atime)
411 printf ("; last read on %s", dtime (&st.st_atime, 1));
420 extern char response[];
423 remotemail (char *host, char *user, char *proxy, int rpop, int kpop, int notifysw, int personal, int snoop, int sasl, char *saslmech)
425 int nmsgs, nbytes, status;
429 user = getusername ();
430 if (kpop || sasl || (rpop > 0))
431 pass = getusername ();
433 ruserpass (host, &user, &pass);
435 /* open the POP connection */
436 if (pop_init (host, user, pass, proxy, snoop, kpop ? 1 : rpop, kpop,
437 sasl, saslmech) == NOTOK
438 || pop_stat (&nmsgs, &nbytes) == NOTOK /* check for messages */
439 || pop_quit () == NOTOK) { /* quit POP connection */
440 advise (NULL, "%s", response);
445 if (notifysw & NT_MAIL) {
446 printf (personal ? "You have " : "%s has ", user);
447 printf ("%d message%s (%d bytes)",
448 nmsgs, nmsgs != 1 ? "s" : "", nbytes);
455 if (notifysw & NT_NMAI)
456 printf (personal ? "You don't %s%s" : "%s doesn't %s",
457 personal ? "" : user, "have any mail waiting");
463 printf (" on %s\n", host);