]>
diplodocus.org Git - nmh/blob - uip/msgchk.c
3 * msgchk.c -- check for mail
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.
18 # define SASLminc(a) (a)
20 # define SASLminc(a) 0
23 #define MSGCHK_SWITCHES \
24 X("date", 0, DATESW) \
25 X("nodate", 0, NDATESW) \
26 X("notify type", 0, NOTESW) \
27 X("nonotify type", 0, NNOTESW) \
28 X("host hostname", 0, HOSTSW) \
29 X("user username", 0, USERSW) \
30 X("port name/number", 0, PORTSW) \
31 X("version", 0, VERSIONSW) \
32 X("help", 0, HELPSW) \
33 X("snoop", 0, SNOOPSW) \
34 X("sasl", SASLminc(4), SASLSW) \
35 X("saslmech", SASLminc(5), SASLMECHSW) \
36 X("authservice", SASLminc(0), AUTHSERVICESW) \
37 X("proxy command", 0, PROXYSW) \
39 #define X(sw, minchars, id) id,
40 DEFINE_SWITCH_ENUM(MSGCHK
);
43 #define X(sw, minchars, id) { sw, minchars, id },
44 DEFINE_SWITCH_ARRAY(MSGCHK
, switches
);
48 * Maximum numbers of users we can check (plus
49 * one for the NULL vector at the end).
55 #endif /* Use NT_NONE to prevent warning from gcc -Wunused-macros. */
58 #define NT_ALL (NT_MAIL | NT_NMAI)
63 #define UUCPOK (UUCPOLD | UUCPNEW)
66 #define MMDFOK (MMDFOLD | MMDFNEW)
72 static int donote (char *, int);
73 static int checkmail (char *, char *, int, int, int);
74 static int remotemail (char *, char *, char *, char *, int, int, int, int,
75 char *, const char *);
79 main (int argc
, char **argv
)
81 int datesw
= 1, notifysw
= NT_ALL
;
82 int status
= 0, sasl
= 0;
83 int snoop
= 0, vecp
= 0;
84 char *cp
, *host
= NULL
, *port
= NULL
, *user
= NULL
, *proxy
= NULL
;
85 char buf
[BUFSIZ
], *saslmech
= NULL
, *auth_svc
= NULL
;
86 char **argp
, **arguments
, *vec
[MAXVEC
];
89 if (nmh_init(argv
[0], 1)) { return 1; }
93 arguments
= getarguments (invo_name
, argc
, argv
, 1);
96 while ((cp
= *argp
++)) {
98 switch (smatch (++cp
, switches
)) {
100 ambigsw (cp
, switches
);
103 adios (NULL
, "-%s unknown", cp
);
106 snprintf (buf
, sizeof(buf
), "%s [switches] [users ...]",
108 print_help (buf
, switches
, 1);
111 print_version(invo_name
);
122 if (!(cp
= *argp
++) || *cp
== '-')
123 adios (NULL
, "missing argument to %s", argp
[-2]);
124 notifysw
|= donote (cp
, 1);
127 if (!(cp
= *argp
++) || *cp
== '-')
128 adios (NULL
, "missing argument to %s", argp
[-2]);
129 notifysw
&= ~donote (cp
, 0);
133 if (!(host
= *argp
++) || *host
== '-')
134 adios (NULL
, "missing argument to %s", argp
[-2]);
138 if (!(port
= *argp
++) || *port
== '-')
139 adios (NULL
, "missing argument to %s", argp
[-2]);
143 if (!(cp
= *argp
++) || *cp
== '-')
144 adios (NULL
, "missing argument to %s", argp
[-2]);
145 if (vecp
>= MAXVEC
-1)
146 adios (NULL
, "you can only check %d users at a time", MAXVEC
-1);
148 user
= vec
[vecp
++] = cp
;
160 if (!(saslmech
= *argp
++) || *saslmech
== '-')
161 adios (NULL
, "missing argument to %s", argp
[-2]);
166 if (!(auth_svc
= *argp
++) || *auth_svc
== '-')
167 adios (NULL
, "missing argument to %s", argp
[-2]);
169 adios (NULL
, "not built with OAuth support");
174 if (!(proxy
= *argp
++) || *proxy
== '-')
175 adios (NULL
, "missing argument to %s", argp
[-2]);
179 if (vecp
>= MAXVEC
-1)
180 adios (NULL
, "you can only check %d users at a time", MAXVEC
-1);
186 * If -host is not specified by user
188 if (!host
|| !*host
) {
190 * If "pophost" is specified in mts.conf,
191 * use it as default value.
193 if (pophost
&& *pophost
)
204 status
= remotemail (host
, port
, user
, proxy
, notifysw
, 1,
205 snoop
, sasl
, saslmech
, auth_svc
);
207 for (vecp
= 0; vec
[vecp
]; vecp
++)
208 status
+= remotemail (host
, port
, vec
[vecp
], proxy
, notifysw
, 0,
209 snoop
, sasl
, saslmech
, auth_svc
);
212 if (user
== NULL
) user
= getusername ();
216 /* Not sure this check makes sense... */
217 if (!geteuid() || NULL
== (home
= getenv("HOME"))) {
218 pw
= getpwnam (user
);
220 adios (NULL
, "unable to get information about user");
223 status
= checkmail (user
, home
, datesw
, notifysw
, 1);
225 for (vecp
= 0; vec
[vecp
]; vecp
++) {
226 if ((pw
= getpwnam (vec
[vecp
])))
227 status
+= checkmail (pw
->pw_name
, pw
->pw_dir
, datesw
, notifysw
, 0);
229 advise (NULL
, "no such user as %s", vec
[vecp
]);
239 #define NOTE_SWITCHES \
240 X("all", 0, NALLSW) \
241 X("mail", 0, NMAISW) \
242 X("nomail", 0, NNMAISW) \
244 #define X(sw, minchars, id) id,
245 DEFINE_SWITCH_ENUM(NOTE
);
248 #define X(sw, minchars, id) { sw, minchars, id },
249 DEFINE_SWITCH_ARRAY(NOTE
, ntswitches
);
254 donote (char *cp
, int ntflag
)
256 switch (smatch (cp
, ntswitches
)) {
258 ambigsw (cp
, ntswitches
);
261 adios (NULL
, "-%snotify %s unknown", ntflag
? "" : "no", cp
);
271 return 0; /* Before 1999-07-15, garbage was returned if control got here. */
276 checkmail (char *user
, char *home
, int datesw
, int notifysw
, int personal
)
282 snprintf (buffer
, sizeof(buffer
), "%s/%s", mmdfldir
[0] ? mmdfldir
: home
, mmdflfil
[0] ? mmdflfil
: user
);
285 st
.st_atime
= st
.st_mtime
= 0;
287 mf
= (stat (buffer
, &st
) == NOTOK
|| st
.st_size
== 0) ? NONEOK
288 : st
.st_atime
<= st
.st_mtime
? MMDFNEW
: MMDFOLD
;
290 if ((mf
& UUCPOK
) || (mf
& MMDFOK
)) {
291 if (notifysw
& NT_MAIL
) {
293 printf ("You have ");
295 printf ("%s has ", user
);
297 printf ("%s old-style bell", mf
& UUCPOLD
? "old" : "new");
298 if ((mf
& UUCPOK
) && (mf
& MMDFOK
))
301 printf ("%s%s", mf
& MMDFOLD
? "old" : "new",
302 mf
& UUCPOK
? " Internet" : "");
303 printf (" mail waiting");
310 if (notifysw
& NT_NMAI
)
311 printf (personal
? "You don't %s%s" : "%s doesn't %s",
312 personal
? "" : user
, "have any mail waiting");
320 if (datesw
&& st
.st_atime
)
321 printf ("; last read on %s", dtime (&st
.st_atime
, 1));
329 extern char response
[];
332 remotemail (char *host
, char *port
, char *user
, char *proxy
, int notifysw
,
333 int personal
, int snoop
, int sasl
, char *saslmech
,
334 const char *auth_svc
)
336 int nmsgs
, nbytes
, status
;
337 struct nmh_creds creds
= { 0, 0, 0 };
339 if (auth_svc
== NULL
) {
340 if (saslmech
&& ! strcasecmp(saslmech
, "xoauth2")) {
341 adios (NULL
, "must specify -authservice with -saslmech xoauth2");
343 nmh_get_credentials (host
, user
, sasl
, &creds
);
346 adios (NULL
, "must specify -user with -saslmech xoauth2");
351 /* open the POP connection */
352 if (pop_init (host
, port
, creds
.user
, creds
.password
, proxy
, snoop
, sasl
,
353 saslmech
, auth_svc
) == NOTOK
354 || pop_stat (&nmsgs
, &nbytes
) == NOTOK
/* check for messages */
355 || pop_quit () == NOTOK
) { /* quit POP connection */
356 advise (NULL
, "%s", response
);
361 if (notifysw
& NT_MAIL
) {
363 printf ("You have ");
365 printf ("%s has ", user
);
367 printf ("%d message%s (%d bytes)",
368 nmsgs
, nmsgs
!= 1 ? "s" : "", nbytes
);
375 if (notifysw
& NT_NMAI
)
376 printf (personal
? "You don't %s%s" : "%s doesn't %s",
377 personal
? "" : user
, "have any mail waiting");
383 printf (" on %s\n", host
);