Removed all POP support
[mmh] / uip / msgchk.c
1
2 /*
3  * msgchk.c -- check for mail
4  *
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.
8  */
9
10 #include <h/mh.h>
11 #include <h/mts.h>
12 #include <h/tws.h>
13 #include <pwd.h>
14
15 static struct swit switches[] = {
16 #define DATESW                   0
17     { "date", 0 },
18 #define NDATESW                  1
19     { "nodate", 0 },
20 #define NOTESW                   2
21     { "notify type", 0 },
22 #define NNOTESW                  3
23     { "nonotify type", 0 },
24 #define VERSIONSW                7
25     { "version", 0 },
26 #define HELPSW                   8
27     { "help", 0 },
28 };
29
30 /*
31  * Maximum numbers of users we can check (plus
32  * one for the NULL vector at the end).
33  */
34 #define MAXVEC  51
35
36 #define NT_NONE 0x0
37 #define NT_MAIL 0x1
38 #define NT_NMAI 0x2
39 #define NT_ALL  (NT_MAIL | NT_NMAI)
40
41 #define NONEOK  0x0
42 #define UUCPOLD 0x1
43 #define UUCPNEW 0x2
44 #define UUCPOK  (UUCPOLD | UUCPNEW)
45 #define MMDFOLD 0x4
46 #define MMDFNEW 0x8
47 #define MMDFOK  (MMDFOLD | MMDFNEW)
48
49
50 /*
51  * static prototypes
52  */
53 static int donote (char *, int);
54 static int checkmail (char *, char *, int, int, int);
55
56
57 int
58 main (int argc, char **argv)
59 {
60     int datesw = 1, notifysw = NT_ALL;
61     int status = 0;
62     int vecp = 0;
63     uid_t uid;
64     char buf[BUFSIZ]; 
65     char *user, *cp;
66     char **argp, **arguments, *vec[MAXVEC];
67     struct passwd *pw;
68
69 #ifdef LOCALE
70     setlocale(LC_ALL, "");
71 #endif
72     invo_name = r1bindex (argv[0], '/');
73
74     /* read user profile/context */
75     context_read();
76
77     mts_init (invo_name);
78     uid = getuid ();
79     user = getusername();
80
81     arguments = getarguments (invo_name, argc, argv, 1);
82     argp = arguments;
83
84     while ((cp = *argp++)) {
85         if (*cp == '-') {
86             switch (smatch (++cp, switches)) {
87                 case AMBIGSW: 
88                     ambigsw (cp, switches);
89                     done (1);
90                 case UNKWNSW: 
91                     adios (NULL, "-%s unknown", cp);
92
93                 case HELPSW: 
94                     snprintf (buf, sizeof(buf), "%s [switches] [users ...]",
95                         invo_name);
96                     print_help (buf, switches, 1);
97                     done (1);
98                 case VERSIONSW:
99                     print_version(invo_name);
100                     done (1);
101
102                 case DATESW:
103                     datesw++;
104                     continue;
105                 case NDATESW:
106                     datesw = 0;
107                     continue;
108
109                 case NOTESW:
110                     if (!(cp = *argp++) || *cp == '-')
111                         adios (NULL, "missing argument to %s", argp[-2]);
112                     notifysw |= donote (cp, 1);
113                     continue;
114                 case NNOTESW:
115                     if (!(cp = *argp++) || *cp == '-')
116                         adios (NULL, "missing argument to %s", argp[-2]);
117                     notifysw &= ~donote (cp, 0);
118                     continue;
119             }
120         }
121         if (vecp >= MAXVEC-1)
122             adios (NULL, "you can only check %d users at a time", MAXVEC-1);
123         else
124             vec[vecp++] = cp;
125     }
126
127     if (vecp != 0)
128         vec[vecp] = NULL;
129
130     if (vecp == 0) {
131         char *home;
132
133         /* Not sure this check makes sense... */
134         if (!geteuid() || NULL == (home = getenv("HOME"))) {
135             pw = getpwnam (user);
136             if (pw == NULL)
137                 adios (NULL, "unable to get information about user");
138             home = pw->pw_dir;
139         }
140         status = checkmail (user, home, datesw, notifysw, 1);
141     } else {
142         for (vecp = 0; vec[vecp]; vecp++) {
143             if ((pw = getpwnam (vec[vecp])))
144                 status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
145             else
146                 advise (NULL, "no such user as %s", vec[vecp]);
147         }
148     }
149
150     done (status);
151     return 1;
152 }
153
154
155 static struct swit ntswitches[] = {
156 #define NALLSW     0
157     { "all", 0 },
158 #define NMAISW     1
159     { "mail", 0 },
160 #define NNMAISW    2
161     { "nomail", 0 },
162     { NULL, 0 }
163 };
164
165
166 static int
167 donote (char *cp, int ntflag)
168 {
169     switch (smatch (cp, ntswitches)) {
170         case AMBIGSW: 
171             ambigsw (cp, ntswitches);
172             done (1);
173         case UNKWNSW: 
174             adios (NULL, "-%snotify %s unknown", ntflag ? "" : "no", cp);
175
176         case NALLSW: 
177             return NT_ALL;
178         case NMAISW: 
179             return NT_MAIL;
180         case NNMAISW: 
181             return NT_NMAI;
182     }
183
184     return 0; /* Before 1999-07-15, garbage was returned if control got here. */
185 }
186
187
188 static int
189 checkmail (char *user, char *home, int datesw, int notifysw, int personal)
190 {
191     int mf, status;
192     char buffer[BUFSIZ];
193     struct stat st;
194
195     snprintf (buffer, sizeof(buffer), "%s/%s", mmdfldir[0] ? mmdfldir : home, mmdflfil[0] ? mmdflfil : user);
196     if (datesw) {
197         st.st_size = 0;
198         st.st_atime = st.st_mtime = 0;
199     }
200     mf = (stat (buffer, &st) == NOTOK || st.st_size == 0) ? NONEOK
201         : st.st_atime <= st.st_mtime ? MMDFNEW : MMDFOLD;
202
203     if ((mf & UUCPOK) || (mf & MMDFOK)) {
204         if (notifysw & NT_MAIL) {
205             printf (personal ? "You have " : "%s has ", user);
206             if (mf & UUCPOK)
207                 printf ("%s old-style bell", mf & UUCPOLD ? "old" : "new");
208             if ((mf & UUCPOK) && (mf & MMDFOK))
209                 printf (" and ");
210             if (mf & MMDFOK)
211                 printf ("%s%s", mf & MMDFOLD ? "old" : "new",
212                         mf & UUCPOK ? " Internet" : "");
213             printf (" mail waiting");
214         } else {
215             notifysw = 0;
216         }
217         status = 0;
218     }
219     else {
220         if (notifysw & NT_NMAI)
221             printf (personal ? "You don't %s%s" : "%s doesn't %s",
222                     personal ? "" : user, "have any mail waiting");
223         else
224             notifysw = 0;
225
226         status = 1;
227     }
228
229     if (notifysw)
230         if (datesw && st.st_atime)
231             printf ("; last read on %s", dtime (&st.st_atime, 1));
232     if (notifysw)
233         printf ("\n");
234
235     return status;
236 }