]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/msgchk.c
Put, rather than print, single characters.
[nmh] / docs / historical / mh-6.8.5 / uip / msgchk.c
1 /* msgchk.c - check for mail */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: msgchk.c,v 1.14 1995/12/06 23:51:28 jromine Exp shettich $";
4 #endif /* lint */
5
6 #include "../h/mh.h"
7 #include <stdio.h>
8 #include "../zotnet/mts.h"
9 #include "../zotnet/tws.h"
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <pwd.h>
13 #ifdef LOCALE
14 #include <locale.h>
15 #endif
16 #ifdef HESIOD
17 #include <hesiod.h>
18 #endif
19
20 /* \f */
21
22 #ifndef POP
23 #define POPminc(a) (a)
24 #else /* POP */
25 #define POPminc(a) 0
26 #endif /* POP */
27
28 #ifndef RPOP
29 #define RPOPminc(a) (a)
30 #else /* RPOP */
31 #define RPOPminc(a) 0
32 #endif /* RPOP */
33
34 #ifndef APOP
35 #define APOPminc(a) (a)
36 #else
37 #define APOPminc(a) 0
38 #endif
39
40 static struct swit switches[] = {
41 #define DATESW 0
42 "date", 0,
43 #define NDATESW 1
44 "nodate", 0,
45
46 #define NOTESW 2
47 "notify type", 0,
48 #define NNOTESW 3
49 "nonotify type", 0,
50
51 #define HOSTSW 4
52 "host host", POPminc (-4),
53 #define USERSW 5
54 "user user", POPminc (-4),
55
56 #define APOPSW 6
57 "apop", APOPminc (-4),
58 #define NAPOPSW 7
59 "noapop", APOPminc (-6),
60
61 #define RPOPSW 8
62 "rpop", RPOPminc (-4),
63 #define NRPOPSW 9
64 "norpop", RPOPminc (-6),
65
66 #define HELPSW 10
67 "help", 4,
68
69 NULL, 0
70 };
71
72 /* \f */
73
74 #define NT_NONE 0x0
75 #define NT_MAIL 0x1
76 #define NT_NMAI 0x2
77 #define NT_ALL (NT_MAIL | NT_NMAI)
78
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 #ifdef SYS5
90 #ifndef __STDC__
91 struct passwd *getpwuid(), *getpwnam();
92 #endif /* !__STDC__ */
93 #endif /* SYS5 */
94
95 static int donote(), checkmail(), remotemail();
96 /* \f */
97
98 /* ARGSUSED */
99
100 main (argc, argv)
101 int argc;
102 char *argv[];
103 {
104 int datesw = 1,
105 notifysw = NT_ALL,
106 #ifdef RPOP
107 rpop = 1,
108 #else
109 rpop = 0,
110 #endif /* RPOP */
111 status = 0,
112 snoop = 0,
113 vecp = 0;
114 int uid = getuid ();
115 char *cp,
116 *host = NULL,
117 buf[80],
118 **ap,
119 **argp,
120 *arguments[MAXARGS],
121 *vec[50];
122 char *user = getusr ();
123 struct passwd *pw;
124 #ifdef HESIOD
125 struct hes_postoffice *po;
126 char *tmphost;
127 #endif
128
129 #ifdef LOCALE
130 setlocale(LC_ALL, "");
131 #endif
132 invo_name = r1bindex (argv[0], '/');
133 mts_init (invo_name);
134 #ifdef POP
135 if ((cp = getenv ("MHPOPDEBUG")) && *cp)
136 snoop++;
137 #endif
138
139 if ((cp = m_find (invo_name)) != NULL) {
140 ap = brkstring (cp = getcpy (cp), " ", "\n");
141 ap = copyip (ap, arguments);
142 }
143 else
144 ap = arguments;
145 (void) copyip (argv + 1, ap);
146 argp = arguments;
147
148 /* \f */
149
150 while (cp = *argp++) {
151 if (*cp == '-')
152 switch (smatch (++cp, switches)) {
153 case AMBIGSW:
154 ambigsw (cp, switches);
155 done (1);
156 case UNKWNSW:
157 adios (NULLCP, "-%s unknown", cp);
158 case HELPSW:
159 (void) sprintf (buf, "%s [switches] [users ...]",
160 invo_name);
161 help (buf, switches);
162 done (1);
163
164 case DATESW:
165 datesw++;
166 continue;
167 case NDATESW:
168 datesw = 0;
169 continue;
170
171 case NOTESW:
172 if (!(cp = *argp++) || *cp == '-')
173 adios (NULLCP, "missing argument to %s", argp[-2]);
174 notifysw |= donote (cp, 1);
175 continue;
176 case NNOTESW:
177 if (!(cp = *argp++) || *cp == '-')
178 adios (NULLCP, "missing argument to %s", argp[-2]);
179 notifysw &= ~donote (cp, 0);
180 continue;
181
182 case HOSTSW:
183 if (!(host = *argp++) || *host == '-')
184 adios (NULLCP, "missing argument to %s", argp[-2]);
185 continue;
186 case USERSW:
187 if (!(cp = *argp++) || *cp == '-')
188 adios (NULLCP, "missing argument to %s", argp[-2]);
189 vec[vecp++] = cp;
190 continue;
191 case APOPSW:
192 rpop = -1;
193 continue;
194 case RPOPSW:
195 rpop = 1;
196 continue;
197 case NAPOPSW:
198 case NRPOPSW:
199 rpop = 0;
200 continue;
201 }
202 vec[vecp++] = cp;
203 }
204
205 /* \f */
206 #ifdef POP
207 if (!host || !*host) { /* -host not specified by user */
208 #ifdef HESIOD
209 /*
210 * Scheme is:
211 * use MAILHOST environment variable if present,
212 * else try Hesiod.
213 * If that fails, use the default (if any)
214 * provided by mtstailor in mts_init()
215 */
216 if ((tmphost = getenv("MAILHOST")) != NULL)
217 pophost = tmphost;
218 else if ((po = hes_getmailhost(vecp ? vec[0] : user)) != NULL &&
219 strcmp(po->po_type, "POP") == 0)
220 pophost = po->po_host;
221 #endif /* HESIOD */
222 if (pophost && *pophost)
223 host = pophost;
224 }
225 if (!host || !*host)
226 host = NULL;
227 if (!host || rpop <= 0)
228 (void) setuid (uid);
229 #endif /* POP */
230 if (vecp == 0) {
231 #ifdef POP
232 if (host)
233 status = remotemail (host, user, rpop, notifysw, 1, snoop);
234 else
235 #endif
236 {
237 char *home = (uid = geteuid()) ? home = getenv ("HOME") : NULL;
238 if (home == NULL)
239 {
240 pw = getpwnam (user);
241 if (pw == NULL)
242 adios (NULLCP, "unable to get information about user");
243 if (home == NULL)
244 home = pw->pw_dir;
245 }
246 status = checkmail (user, home, datesw, notifysw, 1);
247 }
248 }
249 else {
250 vec[vecp] = NULL;
251
252 for (vecp = 0; cp = vec[vecp]; vecp++)
253 #ifdef POP
254 if (host)
255 status += remotemail (host, cp, rpop, notifysw, 0, snoop);
256 else
257 #endif
258 if (pw = getpwnam (cp))
259 status += checkmail (pw->pw_name, pw->pw_dir, datesw, notifysw, 0);
260 else
261 advise (NULLCP, "no such user as %s", cp);
262 }
263
264 done (status);
265 }
266
267 /* \f */
268
269 static struct swit ntswitches[] = {
270 #define NALLSW 0
271 "all", 0,
272 #define NMAISW 1
273 "mail", 0,
274 #define NNMAISW 2
275 "nomail", 0,
276
277 NULL, 0
278 };
279
280
281 static int donote (cp, ntflag)
282 register char *cp;
283 int ntflag;
284 {
285 switch (smatch (cp, ntswitches)) {
286 case AMBIGSW:
287 ambigsw (cp, ntswitches);
288 done (1);
289 case UNKWNSW:
290 adios (NULLCP, "-%snotify %s unknown", ntflag ? "" : "no", cp);
291
292 case NALLSW:
293 return NT_ALL;
294 case NMAISW:
295 return NT_MAIL;
296 case NNMAISW:
297 return NT_NMAI;
298 }
299 }
300
301 /* \f */
302
303 #ifdef MF
304 /* ARGSUSED */
305 #endif /* MF */
306
307 static int checkmail (user, home, datesw, notifysw, personal)
308 register char *user, *home;
309 int datesw,
310 notifysw,
311 personal;
312 {
313 int mf,
314 status;
315 char buffer[BUFSIZ];
316 struct stat st;
317
318 (void) sprintf (buffer, "%s/%s",
319 mmdfldir[0] ? mmdfldir : home,
320 mmdflfil[0] ? mmdflfil : user);
321 #ifndef MF
322 if (datesw) {
323 st.st_size = 0;
324 st.st_atime = st.st_mtime = 0;
325 }
326 #endif /* MF */
327 mf = (stat (buffer, &st) == NOTOK || st.st_size == 0) ? NONEOK
328 : st.st_atime <= st.st_mtime ? MMDFNEW : MMDFOLD;
329
330 #ifdef MF
331 if (umincproc != NULL && *umincproc != NULL) {
332 (void) sprintf (buffer, "%s/%s",
333 uucpldir[0] ? uucpldir : home,
334 uucplfil[0] ? uucplfil : user);
335 mf |= (stat (buffer, &st) == NOTOK || st.st_size == 0) ? NONEOK
336 : st.st_atime <= st.st_mtime ? UUCPNEW : UUCPOLD;
337 }
338 #endif /* MF */
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 }
352 else
353 notifysw = 0;
354
355 status = 0;
356 }
357 else {
358 if (notifysw & NT_NMAI)
359 printf (personal ? "You don't %s%s" : "%s doesn't %s",
360 personal ? "" : user, "have any mail waiting");
361 else
362 notifysw = 0;
363
364 status = 1;
365 }
366
367 #ifndef MF
368 if (notifysw)
369 if (datesw && st.st_atime)
370 printf ("; last read on %s",
371 dasctime (dlocaltime ((long *) & st.st_atime), TW_NULL));
372 #endif /* MF */
373 if (notifysw)
374 printf ("\n");
375
376 return status;
377 }
378
379 /* \f */
380
381 #ifdef POP
382 extern char response[];
383
384
385 static int remotemail (host, user, rpop, notifysw, personal, snoop)
386 register char *host;
387 char *user;
388 int rpop,
389 notifysw,
390 personal,
391 snoop;
392 {
393 int nmsgs,
394 nbytes,
395 status;
396 char *pass = NULL;
397
398 if (user == NULL)
399 user = getusr ();
400 if (rpop > 0)
401 pass = getusr ();
402 else
403 ruserpass (host, &user, &pass);
404
405 if (pop_init (host, user, pass, snoop, rpop) == NOTOK
406 || pop_stat (&nmsgs, &nbytes) == NOTOK
407 || pop_quit () == NOTOK) {
408 advise (NULLCP, "%s", response);
409 return 1;
410 }
411
412 if (nmsgs) {
413 if (notifysw & NT_MAIL) {
414 printf (personal ? "You have " : "%s has ", user);
415 printf ("%d message%s (%d bytes)",
416 nmsgs, nmsgs != 1 ? "s" : "", nbytes);
417 }
418 else
419 notifysw = 0;
420
421 status = 0;
422 }
423 else {
424 if (notifysw & NT_NMAI)
425 printf (personal ? "You don't %s%s" : "%s doesn't %s",
426 personal ? "" : user, "have any mail waiting");
427 else
428 notifysw = 0;
429 status = 1;
430 }
431 if (notifysw)
432 printf (" on %s\n", host);
433
434 return status;
435 }
436 #endif /* POP */