9 date 93.08.25.17.29.36; author jromine; state Exp;
14 date 92.11.04.01.05.01; author jromine; state Exp;
19 date 92.02.03.16.37.06; author jromine; state Exp;
24 date 92.02.03.16.36.33; author jromine; state Exp;
35 @off_t fixes for BSD44
38 @/* umhook.c - one attempt at a rcvmail hook for UUCP mail */
40 static char ident[] = "@@(#)$Id: umhook.c,v 1.3 1992/11/04 01:05:01 jromine Exp jromine $";
43 /* I don't comment my code heavily, so read this...
45 You run this program from your .login file. The invocation is simply
46 "umhook". The program "detaches" itself and runs unattended until you
47 logout. Whenever you get UUCP mail (or upto a minute afterwards),
48 umhook will filter your UUCP mail drop to a temporary file. The mail
49 drop is *NOT* touched beyond this (even the access time remains the
50 same). For each message that was new in the mail drop, umhook will
51 fork a process to interpret your .maildelivery file.
53 The umhook program uses the -ljobs control facility to do two things:
54 - determine when the controlling tty has gone away
55 - kill a child that's run away (the child sets up a process group)
59 #include "../zotnet/mf.h"
61 #include "../zotnet/mts.h"
64 #include <sys/ioctl.h>
65 #include <sys/types.h>
73 static struct swit switches[] = {
85 static int snooze = 60;
87 static int uucp = NOTOK;
91 static char myhome[BUFSIZ] = "";
92 static char mymail[BUFSIZ] = "";
93 static char myaddr[BUFSIZ] = "";
94 static char mystat[BUFSIZ] = "";
95 static char myuser[BUFSIZ] = "";
102 struct passwd *getpwuid ();
103 #endif /* !__STDC__ */
122 setlocale(LC_ALL, "");
124 invo_name = r1bindex (argv[0], '/');
125 mts_init (invo_name);
126 if ((cp = m_find (invo_name)) != NULL) {
127 ap = brkstring (cp = getcpy (cp), " ", "\n");
128 ap = copyip (ap, arguments);
132 (void) copyip (argv + 1, ap);
137 while (cp = *argp++) {
139 switch (smatch (++cp, switches)) {
141 ambigsw (cp, switches);
144 adios (NULLCP, "-%s unknown", cp);
146 (void) sprintf (buf, "%s [switches]", invo_name);
147 help (buf, switches);
151 if (!(cp = *argp++) || *cp == '-')
152 adios (NULLCP, "missing argument to %s", argp[-2]);
153 if ((snooze = atoi (cp)) < 0)
154 adios (NULLCP, "bad argument %s %s", argp[-2], cp);
157 adios (NULLCP, "usage: %s [switches]", invo_name);
162 if ((pw = getpwuid (getuid ())) == NULL)
163 adios (NULLCP, "you lose big");
166 (void) m_putenv ("USER", pw -> pw_name);
167 (void) m_putenv ("HOME", pw -> pw_dir);
168 (void) m_putenv ("SHELL", pw -> pw_shell);
169 if (chdir (pw -> pw_dir) == NOTOK)
173 if (geteuid () == 0) {
175 (void) inigrp (pw -> pw_name, pw -> pw_gid);
177 (void) setgid (pw -> pw_gid);
179 (void) initgroups (pw -> pw_name, pw -> pw_gid);
181 (void) setuid (pw -> pw_uid);
184 (void) sprintf (mymail, "%s/%s",
185 uucpldir[0] ? uucpldir : pw -> pw_dir,
186 uucplfil[0] ? uucplfil : pw -> pw_name);
187 (void) strcpy (myuser, pw -> pw_name);
188 (void) sprintf (myaddr, "%s@@%s", pw -> pw_name, LocalName ());
189 (void) strcpy (myhome, pw -> pw_dir);
190 (void) sprintf (mystat, ".%s_%d", invo_name, pw -> pw_uid);
192 if (access (slocalproc, 1) == NOTOK)
193 adios (slocalproc, "unable to execute");
195 closefds (fileno (stderr) + 1);
197 (void) signal (SIGINT, SIG_IGN);
198 (void) signal (SIGHUP, sigser);
199 (void) signal (SIGQUIT, SIG_IGN);
200 (void) signal (SIGTERM, sigser);
218 #define pgrp_ok(pg) 1
220 #define pgrp_ok(pg) (ioctl (2, TIOCGPGRP, (char *) &pg) != NOTOK)
230 for (; pgrp_ok (pg);) {
231 if (stat (mymail, &st2) == NOTOK) {
232 st2.st_ino = (ino_t) 0;
233 st2.st_size = (off_t) 0;
234 st2.st_mtime = (time_t) 0;
237 if (st1.st_mtime != st2.st_mtime)
238 if (st1.st_ino != st2.st_ino)
239 process ((off_t) 0, &st2);
241 if (st1.st_size < st2.st_size)
242 process (st1.st_size, &st2);
244 st1.st_ino = st2.st_ino;
245 st1.st_size = st2.st_size;
246 st1.st_mtime = st2.st_mtime;
248 sleep ((unsigned) snooze);
254 static process (offset, st)
264 if ((uucp = lkopen (mymail, 0)) == NOTOK)
265 adios (NULLCP, "unable to lock and open %s", mymail);
266 if (lseek (uucp, (off_t) offset, 0) == (off_t) NOTOK)
267 adios (mymail, "unable to position to %ld offset on", (long) offset);
269 (void) strcpy (tmpfil, m_tmpfil (invo_name));
270 if ((td1 = creat (tmpfil, TMPMODE)) == NOTOK)
271 adios (tmpfil, "unable to create");
274 if ((td1 = open (tmpfil, 2)) == NOTOK)
275 adios (tmpfil, "unable to open");
276 (void) unlink (tmpfil);
277 if ((td2 = dup (td1)) == NOTOK)
278 adios ("file descriptor", "unable to dup");
280 switch (uucp2mmdf (uucp, td1, FALSE)) {
282 adios (NULLCP, "internal error while filtering UUCP mail");
285 adios (NULLCP, "no free file pointers");
288 adios ("UUCP mail", "i/o error while filtering");
294 timep[0] = st -> st_atime;
295 timep[1] = st -> st_mtime;
296 utime (mymail, timep);
300 (void) lkclose (uucp, mymail), uucp = NOTOK;
306 (void) lseek (td2, (off_t)0, 0);
307 if ((fp = fdopen (td2, "r")) == NULL)
308 adios (NULLCP, "no free file pointers");
330 if (fgets (buffer, sizeof buffer, in) == NULL)
333 /* should insist on isdlm1 (buffer) here... */
335 (void) strcpy (myfile, m_tmpfil (invo_name));
336 if ((fd1 = creat (myfile, TMPMODE)) == NOTOK)
337 adios (myfile, "unable to create");
340 if ((fd1 = open (myfile, 2)) == NOTOK)
341 adios (myfile, "unable to open");
342 (void) unlink (myfile);
343 if ((fd2 = dup (fd1)) == NOTOK)
344 adios ("file descriptor", "unable to dup");
346 if ((out = fdopen (fd1, "w")) == NULL)
347 adios (NULLCP, "no free file pointers");
349 for (done = TRUE;;) {
350 if (fgets (buffer, sizeof buffer, in) == NULL)
351 break; /* should be error */
352 if (done && isdlm2 (buffer))
354 done = buffer[strlen (buffer) - 1] == '\n';
359 (void) lseek (fd2, (off_t)0, 0);
360 seeksndr (fd2, mysndr);
364 switch (child_id = fork ()) {
366 adios ("fork", "unable to");/* NOTREACHED */
369 (void) lseek (fd2, (off_t)0, 0);
371 (void) dup2 (fd2, 0);
372 (void) freopen ("/dev/null", "w", stdout);
373 (void) freopen ("/dev/null", "w", stderr);
375 (void) dup2 (fd2, 3);
378 if ((i = open ("/dev/tty", 2)) != NOTOK) {
379 (void) ioctl (i, TIOCNOTTY, NULLCP);
384 (void) setpgrp (0, getpid ());
387 execlp (slocalproc, r1bindex (slocalproc, '/'),
388 "-file", myfile, "-mailbox", mymail,
389 "-home", myhome, "-addr", myaddr,
390 "-user", myuser, "-sender", mysndr, NULLCP);
391 adios (slocalproc, "unable to exec");/* NOTREACHED */
395 (void) pidwait (child_id, OK);
402 static seeksndr (fd1, mysndr)
413 if ((fd2 = dup (fd1)) == NOTOK)
414 adios ("file descriptor", "unable to dup");
415 if ((in = fdopen (fd2, "r")) == NULL)
416 adios (NULLCP, "no free file pointers");
418 for (from[0] = sender[0] = NULL; mfgets (in, &hp) != DONE;)
419 if ((bp = index (hp, ':')) != NULL) {
421 if (lequal (hp, "From"))
424 if (lequal (hp, "Sender"))
425 seekaddr (sender, bp);
429 (void) strcpy (mysndr, sender[0] ? sender : from[0] ? from : myaddr);
434 static seekaddr (addr, bp)
440 if ((adrxp = seekadrx (bp)) == NULL)
442 if (adrxp -> err || !adrxp -> mbox)
446 (void) sprintf (addr, "%s@@%s", adrxp -> mbox, adrxp -> host);
448 (void) strcpy (addr, adrxp -> mbox);
450 while (seekadrx (NULLCP))
461 if ((fd = open (mystat, 0)) == NOTOK
462 || read (fd, (char *) st, sizeof *st) != (sizeof *st)) {
463 st -> st_ino = (ino_t) 0;
464 st -> st_size = (off_t) 0;
465 st -> st_mtime = (time_t) 0;
475 static int fd = NOTOK;
478 && (fd = creat (mystat, TMPMODE)) == NOTOK)
479 adios (mystat, "unable to write");
481 (void) lseek (fd, (off_t)0, 0);
482 if (write (fd, (char *) st, sizeof *st) != (sizeof *st))
483 adios (mystat, "error writing");
492 static int sigser (sig)
496 (void) signal (sig, SIG_IGN);
507 (void) lkclose (uucp, mymail), uucp = NOTOK;
521 static char ident[] = "@@(#)$Id: umhook.c,v 1.2 1992/02/03 16:37:06 jromine Exp jromine $";
527 if (lseek (uucp, (long) offset, 0) == (long) NOTOK)
528 adios (mymail, "unable to position to %ld offset on", offset);
531 (void) lseek (td2, 0L, 0);
534 (void) lseek (fd2, 0L, 0);
537 (void) lseek (fd2, 0L, 0);
540 (void) lseek (fd, 0L, 0);
551 static char ident[] = "@@(#)$Id: scan.c,v 1.10 1992/01/31 22:26:24 jromine Exp $";
556 (void) putenv ("USER", pw -> pw_name);
557 (void) putenv ("HOME", pw -> pw_dir);
558 (void) putenv ("SHELL", pw -> pw_shell);