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