source: trunk/third/nmh/uip/msgchk.c @ 12485

Revision 12485, 8.8 KB checked in by danw, 26 years ago (diff)
if MAILDROP is set, make it take precedence over pop
Line 
1
2/*
3 * msgchk.c -- check for mail
4 *
5 * $Id: msgchk.c,v 1.2 1999-02-13 00:39:50 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <zotnet/mts/mts.h>
10#include <zotnet/tws/tws.h>
11#include <pwd.h>
12
13#ifdef POP
14# include <h/popsbr.h>
15#endif
16
17#ifdef HESIOD
18# include <hesiod.h>
19#endif
20
21#ifndef POP
22# define POPminc(a) (a)
23#else
24# define POPminc(a)  0
25#endif
26
27#ifndef RPOP
28# define RPOPminc(a) (a)
29#else
30# define RPOPminc(a)  0
31#endif
32
33#ifndef APOP
34# define APOPminc(a) (a)
35#else
36# define APOPminc(a)  0
37#endif
38
39static struct swit switches[] = {
40#define DATESW                   0
41    { "date", 0 },
42#define NDATESW                  1
43    { "nodate", 0 },
44#define NOTESW                   2
45    { "notify type", 0 },
46#define NNOTESW                  3
47    { "nonotify type", 0 },
48#define HOSTSW                   4
49    { "host hostname", POPminc (-4) },
50#define USERSW                   5
51    { "user username", POPminc (-4) },
52#define APOPSW                   6
53    { "apop", APOPminc (-4) },
54#define NAPOPSW                  7
55    { "noapop", APOPminc (-6) },
56#define RPOPSW                   8
57    { "rpop", RPOPminc (-4) },
58#define NRPOPSW                  9
59    { "norpop", RPOPminc (-6) },
60#define VERSIONSW               10
61    { "version", 0 },
62#define HELPSW                  11
63    { "help", 4 },
64#define SNOOPSW                 12
65    { "snoop", -5 },
66    { NULL, 0 }
67};
68
69/*
70 * Maximum numbers of users we can check (plus
71 * one for the NULL vector at the end).
72 */
73#define MAXVEC  51
74
75#define NT_NONE 0x0
76#define NT_MAIL 0x1
77#define NT_NMAI 0x2
78#define NT_ALL  (NT_MAIL | NT_NMAI)
79
80#define NONEOK  0x0
81#define UUCPOLD 0x1
82#define UUCPNEW 0x2
83#define UUCPOK  (UUCPOLD | UUCPNEW)
84#define MMDFOLD 0x4
85#define MMDFNEW 0x8
86#define MMDFOK  (MMDFOLD | MMDFNEW)
87
88
89/*
90 * static prototypes
91 */
92static int donote (char *, int);
93static int checkmail (char *, char *, int, int, int);
94
95#ifdef POP
96static int remotemail (char *, char *, int, int, int, int);
97#endif
98
99
100int
101main (int argc, char **argv)
102{
103    int datesw = 1, notifysw = NT_ALL;
104    int rpop, status = 0;
105    int snoop = 0, vecp = 0;
106    uid_t uid;
107    char *cp, *host = NULL, *user, buf[BUFSIZ];
108    char **argp, **arguments, *vec[MAXVEC];
109    struct passwd *pw;
110
111#ifdef HESIOD
112    struct hes_postoffice *po;
113    char *tmphost;
114#endif
115
116#ifdef LOCALE
117    setlocale(LC_ALL, "");
118#endif
119    invo_name = r1bindex (argv[0], '/');
120
121    /* read user profile/context */
122    context_read();
123
124    mts_init (invo_name);
125    uid = getuid ();
126    user = getusername();
127
128    arguments = getarguments (invo_name, argc, argv, 1);
129    argp = arguments;
130
131#ifdef POP
132    if ((cp = getenv ("MHPOPDEBUG")) && *cp)
133        snoop++;
134#endif
135
136#ifdef KPOP
137    rpop = 1;
138#else
139    rpop = 0;
140#endif
141
142    while ((cp = *argp++)) {
143        if (*cp == '-') {
144            switch (smatch (++cp, switches)) {
145                case AMBIGSW:
146                    ambigsw (cp, switches);
147                    done (1);
148                case UNKWNSW:
149                    adios (NULL, "-%s unknown", cp);
150
151                case HELPSW:
152                    snprintf (buf, sizeof(buf), "%s [switches] [users ...]",
153                        invo_name);
154                    print_help (buf, switches, 1);
155                    done (1);
156                case VERSIONSW:
157                    print_version(invo_name);
158                    done (1);
159
160                case DATESW:
161                    datesw++;
162                    continue;
163                case NDATESW:
164                    datesw = 0;
165                    continue;
166
167                case NOTESW:
168                    if (!(cp = *argp++) || *cp == '-')
169                        adios (NULL, "missing argument to %s", argp[-2]);
170                    notifysw |= donote (cp, 1);
171                    continue;
172                case NNOTESW:
173                    if (!(cp = *argp++) || *cp == '-')
174                        adios (NULL, "missing argument to %s", argp[-2]);
175                    notifysw &= ~donote (cp, 0);
176                    continue;
177
178                case HOSTSW:
179                    if (!(host = *argp++) || *host == '-')
180                        adios (NULL, "missing argument to %s", argp[-2]);
181                    continue;
182                case USERSW:
183                    if (!(cp = *argp++) || *cp == '-')
184                        adios (NULL, "missing argument to %s", argp[-2]);
185                    if (vecp >= MAXVEC-1)
186                        adios (NULL, "you can only check %d users at a time", MAXVEC-1);
187                    else
188                        vec[vecp++] = cp;
189                    continue;
190
191                case APOPSW:
192                    rpop = -1;
193                    continue;
194                case NAPOPSW:
195                    rpop = 0;
196                    continue;
197
198                case RPOPSW:
199                    rpop = 1;
200                    continue;
201                case NRPOPSW:
202                    rpop = 0;
203                    continue;
204
205                case SNOOPSW:
206                    snoop++;
207                    continue;
208            }
209        }
210        if (vecp >= MAXVEC-1)
211            adios (NULL, "you can only check %d users at a time", MAXVEC-1);
212        else
213            vec[vecp++] = cp;
214    }
215
216#ifdef POP
217    /*
218     * If -host is not specified by user
219     */
220    if ((!host || !*host) && !getenv("MAILDROP")) {
221# ifdef HESIOD
222        /*
223         * Scheme is:
224         *        use MAILHOST environment variable if present,
225         *  else try Hesiod.
226         *  If that fails, use the default (if any)
227         *  provided by mts.conf in mts_init()
228         */
229        if ((tmphost = getenv("MAILHOST")) != NULL)
230            pophost = tmphost;
231        else if ((po = hes_getmailhost(vecp ? vec[0] : user)) != NULL &&
232                strcmp(po->po_type, "POP") == 0)
233            pophost = po->po_host;
234# endif /* HESIOD */
235        /*
236         * If "pophost" is specified in mts.conf,
237         * use it as default value.
238         */
239        if (pophost && *pophost)
240            host = pophost;
241    }
242    if (!host || !*host)
243        host = NULL;
244    if (!host || rpop <= 0)
245        setuid (uid);
246#endif /* POP */
247
248    if (vecp != 0)
249        vec[vecp] = NULL;
250
251#ifdef POP
252    if (host) {
253        if (vecp == 0) {
254            status = remotemail (host, user, rpop, notifysw, 1, snoop);
255        } else {
256            for (vecp = 0; vec[vecp]; vecp++)
257                status += remotemail (host, vec[vecp], rpop, notifysw, 0, snoop);
258        }
259    } else {
260#endif /* POP */
261
262    if (vecp == 0) {
263        char *home;
264
265        home = (uid = geteuid()) ? home = getenv ("HOME") : NULL;
266        if (home == NULL) {
267            pw = getpwnam (user);
268            if (pw == NULL)
269                adios (NULL, "unable to get information about user");
270            if (home == NULL)
271                home = pw->pw_dir;
272        }
273        status = checkmail (user, home, datesw, notifysw, 1);
274    } else {
275        for (vecp = 0; vec[vecp]; vecp++) {
276            if ((pw = getpwnam (vec[vecp])))
277                status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
278            else
279                advise (NULL, "no such user as %s", vec[vecp]);
280        }
281    }
282#ifdef POP
283    }           /* host == NULL */
284#endif
285
286    done (status);
287}
288
289
290static struct swit ntswitches[] = {
291#define NALLSW     0
292    { "all", 0 },
293#define NMAISW     1
294    { "mail", 0 },
295#define NNMAISW    2
296    { "nomail", 0 },
297    { NULL, 0 }
298};
299
300
301static int
302donote (char *cp, int ntflag)
303{
304    switch (smatch (cp, ntswitches)) {
305        case AMBIGSW:
306            ambigsw (cp, ntswitches);
307            done (1);
308        case UNKWNSW:
309            adios (NULL, "-%snotify %s unknown", ntflag ? "" : "no", cp);
310
311        case NALLSW:
312            return NT_ALL;
313        case NMAISW:
314            return NT_MAIL;
315        case NNMAISW:
316            return NT_NMAI;
317    }
318}
319
320
321static int
322checkmail (char *user, char *home, int datesw, int notifysw, int personal)
323{
324    int mf, status;
325    char buffer[BUFSIZ], *maildrop;
326    struct stat st;
327
328    maildrop = getenv("MAILDROP");
329    if (!maildrop) {
330        snprintf (buffer, sizeof(buffer), "%s/%s", mmdfldir[0] ? mmdfldir : home, mmdflfil[0] ? mmdflfil : user);
331        maildrop = buffer;
332    }
333    if (datesw) {
334        st.st_size = 0;
335        st.st_atime = st.st_mtime = 0;
336    }
337    mf = (stat (maildrop, &st) == NOTOK || st.st_size == 0) ? NONEOK
338        : st.st_atime <= st.st_mtime ? MMDFNEW : MMDFOLD;
339
340    if ((mf & UUCPOK) || (mf & MMDFOK)) {
341        if (notifysw & NT_MAIL) {
342            printf (personal ? "You have " : "%s has ", user);
343            if (mf & UUCPOK)
344                printf ("%s old-style bell", mf & UUCPOLD ? "old" : "new");
345            if ((mf & UUCPOK) && (mf & MMDFOK))
346                printf (" and ");
347            if (mf & MMDFOK)
348                printf ("%s%s", mf & MMDFOLD ? "old" : "new",
349                        mf & UUCPOK ? " Internet" : "");
350            printf (" mail waiting");
351        } else {
352            notifysw = 0;
353        }
354        status = 0;
355    }
356    else {
357        if (notifysw & NT_NMAI)
358            printf (personal ? "You don't %s%s" : "%s doesn't %s",
359                    personal ? "" : user, "have any mail waiting");
360        else
361            notifysw = 0;
362
363        status = 1;
364    }
365
366    if (notifysw)
367        if (datesw && st.st_atime)
368            printf ("; last read on %s", dtime (&st.st_atime, 1));
369    if (notifysw)
370        printf ("\n");
371
372    return status;
373}
374
375
376#ifdef POP
377extern char response[];
378
379static int
380remotemail (char *host, char *user, int rpop, int notifysw, int personal, int snoop)
381{
382    int nmsgs, nbytes, status;
383    char *pass = NULL;
384
385    if (user == NULL)
386        user = getusername ();
387    if (rpop > 0)
388        pass = getusername ();
389    else
390        ruserpass (host, &user, &pass);
391
392    /* open the POP connection */
393    if (pop_init (host, user, pass, snoop, rpop) == NOTOK
394            || pop_stat (&nmsgs, &nbytes) == NOTOK      /* check for messages  */
395            || pop_quit () == NOTOK) {                  /* quit POP connection */
396        advise (NULL, "%s", response);
397        return 1;
398    }
399
400    if (nmsgs) {
401        if (notifysw & NT_MAIL) {
402            printf (personal ? "You have " : "%s has ", user);
403            printf ("%d message%s (%d bytes)",
404                    nmsgs, nmsgs != 1 ? "s" : "", nbytes);
405        }
406        else
407            notifysw = 0;
408
409        status = 0;
410    } else {
411        if (notifysw & NT_NMAI)
412            printf (personal ? "You don't %s%s" : "%s doesn't %s",
413                    personal ? "" : user, "have any mail waiting");
414        else
415            notifysw = 0;
416        status = 1;
417    }
418    if (notifysw)
419        printf (" on %s\n", host);
420
421    return status;
422}
423#endif /* POP */
Note: See TracBrowser for help on using the repository browser.