]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/umhook.c
1 /* umhook.c - one attempt at a rcvmail hook for UUCP mail */
3 static char ident
[] = "@(#)$Id: umhook.c,v 1.4 1993/08/25 17:29:36 jromine Exp $";
6 /* I don't comment my code heavily, so read this...
8 You run this program from your .login file. The invocation is simply
9 "umhook". The program "detaches" itself and runs unattended until you
10 logout. Whenever you get UUCP mail (or upto a minute afterwards),
11 umhook will filter your UUCP mail drop to a temporary file. The mail
12 drop is *NOT* touched beyond this (even the access time remains the
13 same). For each message that was new in the mail drop, umhook will
14 fork a process to interpret your .maildelivery file.
16 The umhook program uses the -ljobs control facility to do two things:
17 - determine when the controlling tty has gone away
18 - kill a child that's run away (the child sets up a process group)
22 #include "../zotnet/mf.h"
24 #include "../zotnet/mts.h"
27 #include <sys/ioctl.h>
28 #include <sys/types.h>
36 static struct swit switches
[] = {
48 static int snooze
= 60;
50 static int uucp
= NOTOK
;
54 static char myhome
[BUFSIZ
] = "";
55 static char mymail
[BUFSIZ
] = "";
56 static char myaddr
[BUFSIZ
] = "";
57 static char mystat
[BUFSIZ
] = "";
58 static char myuser
[BUFSIZ
] = "";
65 struct passwd
*getpwuid ();
66 #endif /* !__STDC__ */
85 setlocale(LC_ALL
, "");
87 invo_name
= r1bindex (argv
[0], '/');
89 if ((cp
= m_find (invo_name
)) != NULL
) {
90 ap
= brkstring (cp
= getcpy (cp
), " ", "\n");
91 ap
= copyip (ap
, arguments
);
95 (void) copyip (argv
+ 1, ap
);
100 while (cp
= *argp
++) {
102 switch (smatch (++cp
, switches
)) {
104 ambigsw (cp
, switches
);
107 adios (NULLCP
, "-%s unknown", cp
);
109 (void) sprintf (buf
, "%s [switches]", invo_name
);
110 help (buf
, switches
);
114 if (!(cp
= *argp
++) || *cp
== '-')
115 adios (NULLCP
, "missing argument to %s", argp
[-2]);
116 if ((snooze
= atoi (cp
)) < 0)
117 adios (NULLCP
, "bad argument %s %s", argp
[-2], cp
);
120 adios (NULLCP
, "usage: %s [switches]", invo_name
);
125 if ((pw
= getpwuid (getuid ())) == NULL
)
126 adios (NULLCP
, "you lose big");
129 (void) m_putenv ("USER", pw
-> pw_name
);
130 (void) m_putenv ("HOME", pw
-> pw_dir
);
131 (void) m_putenv ("SHELL", pw
-> pw_shell
);
132 if (chdir (pw
-> pw_dir
) == NOTOK
)
136 if (geteuid () == 0) {
138 (void) inigrp (pw
-> pw_name
, pw
-> pw_gid
);
140 (void) setgid (pw
-> pw_gid
);
142 (void) initgroups (pw
-> pw_name
, pw
-> pw_gid
);
144 (void) setuid (pw
-> pw_uid
);
147 (void) sprintf (mymail
, "%s/%s",
148 uucpldir
[0] ? uucpldir
: pw
-> pw_dir
,
149 uucplfil
[0] ? uucplfil
: pw
-> pw_name
);
150 (void) strcpy (myuser
, pw
-> pw_name
);
151 (void) sprintf (myaddr
, "%s@%s", pw
-> pw_name
, LocalName ());
152 (void) strcpy (myhome
, pw
-> pw_dir
);
153 (void) sprintf (mystat
, ".%s_%d", invo_name
, pw
-> pw_uid
);
155 if (access (slocalproc
, 1) == NOTOK
)
156 adios (slocalproc
, "unable to execute");
158 closefds (fileno (stderr
) + 1);
160 (void) signal (SIGINT
, SIG_IGN
);
161 (void) signal (SIGHUP
, sigser
);
162 (void) signal (SIGQUIT
, SIG_IGN
);
163 (void) signal (SIGTERM
, sigser
);
181 #define pgrp_ok(pg) 1
183 #define pgrp_ok(pg) (ioctl (2, TIOCGPGRP, (char *) &pg) != NOTOK)
193 for (; pgrp_ok (pg
);) {
194 if (stat (mymail
, &st2
) == NOTOK
) {
195 st2
.st_ino
= (ino_t
) 0;
196 st2
.st_size
= (off_t
) 0;
197 st2
.st_mtime
= (time_t) 0;
200 if (st1
.st_mtime
!= st2
.st_mtime
)
201 if (st1
.st_ino
!= st2
.st_ino
)
202 process ((off_t
) 0, &st2
);
204 if (st1
.st_size
< st2
.st_size
)
205 process (st1
.st_size
, &st2
);
207 st1
.st_ino
= st2
.st_ino
;
208 st1
.st_size
= st2
.st_size
;
209 st1
.st_mtime
= st2
.st_mtime
;
211 sleep ((unsigned) snooze
);
217 static process (offset
, st
)
227 if ((uucp
= lkopen (mymail
, 0)) == NOTOK
)
228 adios (NULLCP
, "unable to lock and open %s", mymail
);
229 if (lseek (uucp
, (off_t
) offset
, 0) == (off_t
) NOTOK
)
230 adios (mymail
, "unable to position to %ld offset on", (long) offset
);
232 (void) strcpy (tmpfil
, m_tmpfil (invo_name
));
233 if ((td1
= creat (tmpfil
, TMPMODE
)) == NOTOK
)
234 adios (tmpfil
, "unable to create");
237 if ((td1
= open (tmpfil
, 2)) == NOTOK
)
238 adios (tmpfil
, "unable to open");
239 (void) unlink (tmpfil
);
240 if ((td2
= dup (td1
)) == NOTOK
)
241 adios ("file descriptor", "unable to dup");
243 switch (uucp2mmdf (uucp
, td1
, FALSE
)) {
245 adios (NULLCP
, "internal error while filtering UUCP mail");
248 adios (NULLCP
, "no free file pointers");
251 adios ("UUCP mail", "i/o error while filtering");
257 timep
[0] = st
-> st_atime
;
258 timep
[1] = st
-> st_mtime
;
259 utime (mymail
, timep
);
263 (void) lkclose (uucp
, mymail
), uucp
= NOTOK
;
269 (void) lseek (td2
, (off_t
)0, 0);
270 if ((fp
= fdopen (td2
, "r")) == NULL
)
271 adios (NULLCP
, "no free file pointers");
293 if (fgets (buffer
, sizeof buffer
, in
) == NULL
)
296 /* should insist on isdlm1 (buffer) here... */
298 (void) strcpy (myfile
, m_tmpfil (invo_name
));
299 if ((fd1
= creat (myfile
, TMPMODE
)) == NOTOK
)
300 adios (myfile
, "unable to create");
303 if ((fd1
= open (myfile
, 2)) == NOTOK
)
304 adios (myfile
, "unable to open");
305 (void) unlink (myfile
);
306 if ((fd2
= dup (fd1
)) == NOTOK
)
307 adios ("file descriptor", "unable to dup");
309 if ((out
= fdopen (fd1
, "w")) == NULL
)
310 adios (NULLCP
, "no free file pointers");
312 for (done
= TRUE
;;) {
313 if (fgets (buffer
, sizeof buffer
, in
) == NULL
)
314 break; /* should be error */
315 if (done
&& isdlm2 (buffer
))
317 done
= buffer
[strlen (buffer
) - 1] == '\n';
322 (void) lseek (fd2
, (off_t
)0, 0);
323 seeksndr (fd2
, mysndr
);
327 switch (child_id
= fork ()) {
329 adios ("fork", "unable to");/* NOTREACHED */
332 (void) lseek (fd2
, (off_t
)0, 0);
334 (void) dup2 (fd2
, 0);
335 (void) freopen ("/dev/null", "w", stdout
);
336 (void) freopen ("/dev/null", "w", stderr
);
338 (void) dup2 (fd2
, 3);
341 if ((i
= open ("/dev/tty", 2)) != NOTOK
) {
342 (void) ioctl (i
, TIOCNOTTY
, NULLCP
);
347 (void) setpgrp (0, getpid ());
350 execlp (slocalproc
, r1bindex (slocalproc
, '/'),
351 "-file", myfile
, "-mailbox", mymail
,
352 "-home", myhome
, "-addr", myaddr
,
353 "-user", myuser
, "-sender", mysndr
, NULLCP
);
354 adios (slocalproc
, "unable to exec");/* NOTREACHED */
358 (void) pidwait (child_id
, OK
);
365 static seeksndr (fd1
, mysndr
)
376 if ((fd2
= dup (fd1
)) == NOTOK
)
377 adios ("file descriptor", "unable to dup");
378 if ((in
= fdopen (fd2
, "r")) == NULL
)
379 adios (NULLCP
, "no free file pointers");
381 for (from
[0] = sender
[0] = NULL
; mfgets (in
, &hp
) != DONE
;)
382 if ((bp
= index (hp
, ':')) != NULL
) {
384 if (lequal (hp
, "From"))
387 if (lequal (hp
, "Sender"))
388 seekaddr (sender
, bp
);
392 (void) strcpy (mysndr
, sender
[0] ? sender
: from
[0] ? from
: myaddr
);
397 static seekaddr (addr
, bp
)
403 if ((adrxp
= seekadrx (bp
)) == NULL
)
405 if (adrxp
-> err
|| !adrxp
-> mbox
)
409 (void) sprintf (addr
, "%s@%s", adrxp
-> mbox
, adrxp
-> host
);
411 (void) strcpy (addr
, adrxp
-> mbox
);
413 while (seekadrx (NULLCP
))
424 if ((fd
= open (mystat
, 0)) == NOTOK
425 || read (fd
, (char *) st
, sizeof *st
) != (sizeof *st
)) {
426 st
-> st_ino
= (ino_t
) 0;
427 st
-> st_size
= (off_t
) 0;
428 st
-> st_mtime
= (time_t) 0;
438 static int fd
= NOTOK
;
441 && (fd
= creat (mystat
, TMPMODE
)) == NOTOK
)
442 adios (mystat
, "unable to write");
444 (void) lseek (fd
, (off_t
)0, 0);
445 if (write (fd
, (char *) st
, sizeof *st
) != (sizeof *st
))
446 adios (mystat
, "error writing");
455 static int sigser (sig
)
459 (void) signal (sig
, SIG_IGN
);
470 (void) lkclose (uucp
, mymail
), uucp
= NOTOK
;