]>
diplodocus.org Git - nmh/blob - uip/msgchk.c
82541ec5beeaf0203a8d19096d7002ec02e309ad
1 /* msgchk.c -- check for mail
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
10 #include "sbr/getarguments.h"
11 #include "sbr/smatch.h"
12 #include "sbr/ambigsw.h"
13 #include "sbr/print_version.h"
14 #include "sbr/print_help.h"
15 #include "sbr/error.h"
25 # define SASLminc(a) (a)
27 # define SASLminc(a) 0
31 # define TLSminc(a) (a)
36 #define MSGCHK_SWITCHES \
37 X("date", 0, DATESW) \
38 X("nodate", 0, NDATESW) \
39 X("notify type", 0, NOTESW) \
40 X("nonotify type", 0, NNOTESW) \
41 X("host hostname", 0, HOSTSW) \
42 X("user username", 0, USERSW) \
43 X("port name/number", 0, PORTSW) \
44 X("version", 0, VERSIONSW) \
45 X("help", 0, HELPSW) \
46 X("snoop", 0, SNOOPSW) \
47 X("sasl", SASLminc(4), SASLSW) \
48 X("nosasl", SASLminc(6), NOSASLSW) \
49 X("saslmech", SASLminc(5), SASLMECHSW) \
50 X("authservice", SASLminc(0), AUTHSERVICESW) \
51 X("tls", TLSminc(-3), TLSSW) \
52 X("initialtls", TLSminc(-10), INITTLSSW) \
53 X("notls", TLSminc(-5), NOTLSSW) \
54 X("certverify", TLSminc(-10), CERTVERSW) \
55 X("nocertverify", TLSminc(-12), NOCERTVERSW) \
56 X("proxy command", 0, PROXYSW) \
58 #define X(sw, minchars, id) id,
59 DEFINE_SWITCH_ENUM(MSGCHK
);
62 #define X(sw, minchars, id) { sw, minchars, id },
63 DEFINE_SWITCH_ARRAY(MSGCHK
, switches
);
67 * Maximum numbers of users we can check (plus
68 * one for the NULL vector at the end).
74 #define NT_ALL (NT_MAIL | NT_NMAI)
80 static int donote (char *, int) PURE
;
81 static int checkmail (char *, char *, int, int, int);
82 static int remotemail (char *, char *, char *, char *, int, int, int, int,
83 char *, int, const char *);
87 main (int argc
, char **argv
)
90 int notifysw
= NT_ALL
;
94 bool noverify
= false;
97 char *cp
, *host
= NULL
, *port
= NULL
, *user
= NULL
, *proxy
= NULL
;
98 char buf
[BUFSIZ
], *saslmech
= NULL
, *auth_svc
= NULL
;
99 char **argp
, **arguments
, *vec
[MAXVEC
];
102 if (nmh_init(argv
[0], true, true)) { return 1; }
106 arguments
= getarguments (invo_name
, argc
, argv
, 1);
109 while ((cp
= *argp
++)) {
111 switch (smatch (++cp
, switches
)) {
113 ambigsw (cp
, switches
);
116 die("-%s unknown", cp
);
119 snprintf (buf
, sizeof(buf
), "%s [switches] [users ...]",
121 print_help (buf
, switches
, 1);
124 print_version(invo_name
);
135 if (!(cp
= *argp
++) || *cp
== '-')
136 die("missing argument to %s", argp
[-2]);
137 notifysw
|= donote (cp
, 1);
140 if (!(cp
= *argp
++) || *cp
== '-')
141 die("missing argument to %s", argp
[-2]);
142 notifysw
&= ~donote (cp
, 0);
146 if (!(host
= *argp
++) || *host
== '-')
147 die("missing argument to %s", argp
[-2]);
151 if (!(port
= *argp
++) || *port
== '-')
152 die("missing argument to %s", argp
[-2]);
156 if (!(cp
= *argp
++) || *cp
== '-')
157 die("missing argument to %s", argp
[-2]);
158 if (vecp
>= MAXVEC
-1)
159 die("you can only check %d users at a time", MAXVEC
-1);
160 user
= vec
[vecp
++] = cp
;
176 if (!(saslmech
= *argp
++) || *saslmech
== '-')
177 die("missing argument to %s", argp
[-2]);
202 if (!(auth_svc
= *argp
++) || *auth_svc
== '-')
203 die("missing argument to %s", argp
[-2]);
205 die("not built with OAuth support");
210 if (!(proxy
= *argp
++) || *proxy
== '-')
211 die("missing argument to %s", argp
[-2]);
215 if (vecp
>= MAXVEC
-1)
216 die("you can only check %d users at a time", MAXVEC
-1);
221 * If -host is not specified by user
223 if (!host
|| !*host
) {
225 * If "pophost" is specified in mts.conf,
226 * use it as default value.
228 if (pophost
&& *pophost
)
241 tlsflag
= P_STARTTLS
;
246 tlsflag
|= P_NOVERIFY
;
249 status
= remotemail (host
, port
, user
, proxy
, notifysw
, 1,
250 snoop
, sasl
, saslmech
, tlsflag
, auth_svc
);
252 for (vecp
= 0; vec
[vecp
]; vecp
++)
253 status
+= remotemail (host
, port
, vec
[vecp
], proxy
, notifysw
, 0,
254 snoop
, sasl
, saslmech
, tlsflag
, auth_svc
);
257 if (user
== NULL
) user
= getusername ();
261 /* Not sure this check makes sense... */
262 if (!geteuid() || NULL
== (home
= getenv("HOME"))) {
263 pw
= getpwnam (user
);
265 die("unable to get information about user");
268 status
= checkmail (user
, home
, datesw
, notifysw
, 1);
270 for (vecp
= 0; vec
[vecp
]; vecp
++) {
271 if ((pw
= getpwnam (vec
[vecp
])))
272 status
+= checkmail (pw
->pw_name
, pw
->pw_dir
, datesw
, notifysw
, 0);
274 inform("no such user as %s", vec
[vecp
]);
284 #define NOTE_SWITCHES \
285 X("all", 0, NALLSW) \
286 X("mail", 0, NMAISW) \
287 X("nomail", 0, NNMAISW) \
289 #define X(sw, minchars, id) id,
290 DEFINE_SWITCH_ENUM(NOTE
);
293 #define X(sw, minchars, id) { sw, minchars, id },
294 DEFINE_SWITCH_ARRAY(NOTE
, ntswitches
);
299 donote (char *cp
, int ntflag
)
301 switch (smatch (cp
, ntswitches
)) {
303 ambigsw (cp
, ntswitches
);
306 die("-%snotify %s unknown", ntflag
? "" : "no", cp
);
316 return 0; /* Before 1999-07-15, garbage was returned if control got here. */
321 checkmail (char *user
, char *home
, int datesw
, int notifysw
, int personal
)
324 snprintf(buffer
, sizeof buffer
, "%s/%s", *mmdfldir
? mmdfldir
: home
,
325 *mmdflfil
? mmdflfil
: user
);
328 bool statok
= stat(buffer
, &st
) != -1;
329 bool empty
= !statok
|| st
.st_size
== 0;
331 if ((empty
&& !(notifysw
& NT_NMAI
)) ||
332 (!empty
&& !(notifysw
& NT_MAIL
))) {
338 fputs("You don't have any mail waiting", stdout
);
340 printf("%s doesn't have any mail waiting", user
);
343 char *kind
= st
.st_mtime
< st
.st_atime
? "old" : "new";
345 printf("You have %s mail waiting", kind
);
347 printf("%s has %s mail waiting", user
, kind
);
351 if (datesw
&& statok
&& st
.st_atime
)
352 printf("; last read on %s", dtime(&st
.st_atime
, 1));
359 extern char response
[];
362 remotemail (char *host
, char *port
, char *user
, char *proxy
, int notifysw
,
363 int personal
, int snoop
, int sasl
, char *saslmech
, int tls
,
364 const char *auth_svc
)
369 if (auth_svc
== NULL
) {
370 if (saslmech
&& ! strcasecmp(saslmech
, "xoauth2")) {
371 die("must specify -authservice with -saslmech xoauth2");
375 die("must specify -user with -saslmech xoauth2");
379 /* open the POP connection */
380 if (pop_init (host
, port
, user
, proxy
, snoop
, sasl
, saslmech
, tls
,
382 || pop_stat (&nmsgs
, &nbytes
) == NOTOK
/* check for messages */
383 || pop_quit () == NOTOK
) { /* quit POP connection */
384 inform("%s", response
);
389 if (notifysw
& NT_MAIL
) {
391 fputs("You have ", stdout
);
393 printf ("%s has ", user
);
395 printf ("%d message%s (%d bytes)",
396 nmsgs
, PLURALS(nmsgs
), nbytes
);
403 if (notifysw
& NT_NMAI
)
404 printf (personal
? "You don't %s%s" : "%s doesn't %s",
405 personal
? "" : user
, "have any mail waiting");
411 printf (" on %s\n", host
);