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