]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/RCS/umhook.c,v
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / uip / RCS / umhook.c,v
1 head 1.4;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.4
9 date 93.08.25.17.29.36; author jromine; state Exp;
10 branches;
11 next 1.3;
12
13 1.3
14 date 92.11.04.01.05.01; author jromine; state Exp;
15 branches;
16 next 1.2;
17
18 1.2
19 date 92.02.03.16.37.06; author jromine; state Exp;
20 branches;
21 next 1.1;
22
23 1.1
24 date 92.02.03.16.36.33; author jromine; state Exp;
25 branches;
26 next ;
27
28
29 desc
30 @@
31
32
33 1.4
34 log
35 @off_t fixes for BSD44
36 @
37 text
38 @/* umhook.c - one attempt at a rcvmail hook for UUCP mail */
39 #ifndef lint
40 static char ident[] = "@@(#)$Id: umhook.c,v 1.3 1992/11/04 01:05:01 jromine Exp jromine $";
41 #endif lint
42
43 /* I don't comment my code heavily, so read this...
44
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.
52
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)
56 */
57
58 #include "../h/mh.h"
59 #include "../zotnet/mf.h"
60 #include <stdio.h>
61 #include "../zotnet/mts.h"
62 #include <pwd.h>
63 #include <signal.h>
64 #include <sys/ioctl.h>
65 #include <sys/types.h>
66 #include <sys/stat.h>
67 #ifdef LOCALE
68 #include <locale.h>
69 #endif
70
71 /* \f */
72
73 static struct swit switches[] = {
74 #define SLEEPSW 0
75 "sleep seconds", 0,
76
77 #define HELPSW 1
78 "help", 4,
79
80 NULL, NULL
81 };
82
83 /* \f */
84
85 static int snooze = 60;
86
87 static int uucp = NOTOK;
88
89 extern char *environ;
90
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] = "";
96
97 int sigser ();
98
99 off_t lseek ();
100 #ifdef SYS5
101 #ifndef __STDC__
102 struct passwd *getpwuid ();
103 #endif /* !__STDC__ */
104 #endif SYS5
105
106 /* \f */
107
108 /* ARGSUSED */
109
110 main (argc, argv)
111 int argc;
112 char **argv;
113 {
114 char *cp,
115 **ap,
116 **argp,
117 buf[100],
118 *arguments[MAXARGS];
119 struct passwd *pw;
120
121 #ifdef LOCALE
122 setlocale(LC_ALL, "");
123 #endif
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);
129 }
130 else
131 ap = arguments;
132 (void) copyip (argv + 1, ap);
133 argp = arguments;
134
135 /* \f */
136
137 while (cp = *argp++) {
138 if (*cp == '-')
139 switch (smatch (++cp, switches)) {
140 case AMBIGSW:
141 ambigsw (cp, switches);
142 done (1);
143 case UNKWNSW:
144 adios (NULLCP, "-%s unknown", cp);
145 case HELPSW:
146 (void) sprintf (buf, "%s [switches]", invo_name);
147 help (buf, switches);
148 done (1);
149
150 case SLEEPSW:
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);
155 continue;
156 }
157 adios (NULLCP, "usage: %s [switches]", invo_name);
158 }
159
160 /* \f */
161
162 if ((pw = getpwuid (getuid ())) == NULL)
163 adios (NULLCP, "you lose big");
164
165 *environ = NULL;
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)
170 (void) chdir ("/");
171 (void) umask (0077);
172
173 if (geteuid () == 0) {
174 #ifdef BSD41A
175 (void) inigrp (pw -> pw_name, pw -> pw_gid);
176 #endif BSD41A
177 (void) setgid (pw -> pw_gid);
178 #ifdef BSD42
179 (void) initgroups (pw -> pw_name, pw -> pw_gid);
180 #endif BSD42
181 (void) setuid (pw -> pw_uid);
182 }
183
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);
191
192 if (access (slocalproc, 1) == NOTOK)
193 adios (slocalproc, "unable to execute");
194
195 closefds (fileno (stderr) + 1);
196
197 (void) signal (SIGINT, SIG_IGN);
198 (void) signal (SIGHUP, sigser);
199 (void) signal (SIGQUIT, SIG_IGN);
200 (void) signal (SIGTERM, sigser);
201
202 switch (fork ()) {
203 case NOTOK:
204 case OK:
205 umhook ();
206 break;
207
208 default:
209 break;
210 }
211
212 exit (0);
213 }
214
215 /* \f */
216
217 #ifndef TIOCGPGRP
218 #define pgrp_ok(pg) 1
219 #else TIOCGPGRP
220 #define pgrp_ok(pg) (ioctl (2, TIOCGPGRP, (char *) &pg) != NOTOK)
221 #endif TIOCGPGRP
222
223 static umhook () {
224 int pg;
225 struct stat st1,
226 st2;
227
228 st_init (&st1);
229
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;
235 }
236 else
237 if (st1.st_mtime != st2.st_mtime)
238 if (st1.st_ino != st2.st_ino)
239 process ((off_t) 0, &st2);
240 else
241 if (st1.st_size < st2.st_size)
242 process (st1.st_size, &st2);
243
244 st1.st_ino = st2.st_ino;
245 st1.st_size = st2.st_size;
246 st1.st_mtime = st2.st_mtime;
247
248 sleep ((unsigned) snooze);
249 }
250 }
251
252 /* \f */
253
254 static process (offset, st)
255 off_t offset;
256 struct stat *st;
257 {
258 int td1,
259 td2;
260 time_t timep[2];
261 char tmpfil[BUFSIZ];
262 register FILE *fp;
263
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);
268
269 (void) strcpy (tmpfil, m_tmpfil (invo_name));
270 if ((td1 = creat (tmpfil, TMPMODE)) == NOTOK)
271 adios (tmpfil, "unable to create");
272 (void) close (td1);
273
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");
279
280 switch (uucp2mmdf (uucp, td1, FALSE)) {
281 case MFPRM:
282 adios (NULLCP, "internal error while filtering UUCP mail");
283
284 case MFSIO:
285 adios (NULLCP, "no free file pointers");
286
287 case MFERR:
288 adios ("UUCP mail", "i/o error while filtering");
289
290 case MFOK:
291 case MFROM:
292 case MFHDR:
293 case MFTXT:
294 timep[0] = st -> st_atime;
295 timep[1] = st -> st_mtime;
296 utime (mymail, timep);
297 st_update (st);
298 break;
299 }
300 (void) lkclose (uucp, mymail), uucp = NOTOK;
301
302 /* \f */
303
304 (void) close (td1);
305
306 (void) lseek (td2, (off_t)0, 0);
307 if ((fp = fdopen (td2, "r")) == NULL)
308 adios (NULLCP, "no free file pointers");
309
310 while (hook (fp))
311 continue;
312 (void) fclose (fp);
313 }
314
315 /* \f */
316
317 static int hook (in)
318 register FILE *in;
319 {
320 int child_id,
321 done,
322 fd1,
323 fd2,
324 i;
325 char buffer[BUFSIZ],
326 mysndr[BUFSIZ],
327 myfile[BUFSIZ];
328 register FILE *out;
329
330 if (fgets (buffer, sizeof buffer, in) == NULL)
331 return FALSE;
332
333 /* should insist on isdlm1 (buffer) here... */
334
335 (void) strcpy (myfile, m_tmpfil (invo_name));
336 if ((fd1 = creat (myfile, TMPMODE)) == NOTOK)
337 adios (myfile, "unable to create");
338 (void) close (fd1);
339
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");
345
346 if ((out = fdopen (fd1, "w")) == NULL)
347 adios (NULLCP, "no free file pointers");
348
349 for (done = TRUE;;) {
350 if (fgets (buffer, sizeof buffer, in) == NULL)
351 break; /* should be error */
352 if (done && isdlm2 (buffer))
353 break;
354 done = buffer[strlen (buffer) - 1] == '\n';
355 fputs (buffer, out);
356 }
357 (void) fclose (out);
358
359 (void) lseek (fd2, (off_t)0, 0);
360 seeksndr (fd2, mysndr);
361
362 /* \f */
363
364 switch (child_id = fork ()) {
365 case NOTOK:
366 adios ("fork", "unable to");/* NOTREACHED */
367
368 case OK:
369 (void) lseek (fd2, (off_t)0, 0);
370 if (fd2 != 0)
371 (void) dup2 (fd2, 0);
372 (void) freopen ("/dev/null", "w", stdout);
373 (void) freopen ("/dev/null", "w", stderr);
374 if (fd2 != 3)
375 (void) dup2 (fd2, 3);
376 closefds (4);
377 #ifdef TIOCNOTTY
378 if ((i = open ("/dev/tty", 2)) != NOTOK) {
379 (void) ioctl (i, TIOCNOTTY, NULLCP);
380 (void) close (i);
381 }
382 #endif TIOCNOTTY
383 #ifdef BSD42
384 (void) setpgrp (0, getpid ());
385 #endif BSD42
386
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 */
392
393 default:
394 (void) close (fd2);
395 (void) pidwait (child_id, OK);
396 return TRUE;
397 }
398 }
399
400 /* \f */
401
402 static seeksndr (fd1, mysndr)
403 int fd1;
404 char *mysndr;
405 {
406 int fd2;
407 char *bp,
408 *hp,
409 from[BUFSIZ],
410 sender[BUFSIZ];
411 register FILE *in;
412
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");
417
418 for (from[0] = sender[0] = NULL; mfgets (in, &hp) != DONE;)
419 if ((bp = index (hp, ':')) != NULL) {
420 *bp++ = NULL;
421 if (lequal (hp, "From"))
422 seekaddr (from, bp);
423 else
424 if (lequal (hp, "Sender"))
425 seekaddr (sender, bp);
426 }
427 (void) fclose (in);
428
429 (void) strcpy (mysndr, sender[0] ? sender : from[0] ? from : myaddr);
430 }
431
432 /* \f */
433
434 static seekaddr (addr, bp)
435 char *addr,
436 *bp;
437 {
438 struct adrx *adrxp;
439
440 if ((adrxp = seekadrx (bp)) == NULL)
441 return;
442 if (adrxp -> err || !adrxp -> mbox)
443 return;
444
445 if (adrxp -> host)
446 (void) sprintf (addr, "%s@@%s", adrxp -> mbox, adrxp -> host);
447 else
448 (void) strcpy (addr, adrxp -> mbox);
449
450 while (seekadrx (NULLCP))
451 continue;
452 }
453
454 /* \f */
455
456 static st_init(st)
457 struct stat *st;
458 {
459 int fd;
460
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;
466 }
467 if (fd != NOTOK)
468 (void) close (fd);
469 }
470
471
472 static st_update(st)
473 struct stat *st;
474 {
475 static int fd = NOTOK;
476
477 if (fd == NOTOK
478 && (fd = creat (mystat, TMPMODE)) == NOTOK)
479 adios (mystat, "unable to write");
480
481 (void) lseek (fd, (off_t)0, 0);
482 if (write (fd, (char *) st, sizeof *st) != (sizeof *st))
483 adios (mystat, "error writing");
484 }
485
486 /* \f */
487
488 #ifdef BSD42
489 /* ARGSUSED */
490 #endif BSD42
491
492 static int sigser (sig)
493 int sig;
494 {
495 #ifndef BSD42
496 (void) signal (sig, SIG_IGN);
497 #endif BSD42
498
499 done (1);
500 }
501
502 /* \f */
503
504 void done (status)
505 int status;
506 {
507 (void) lkclose (uucp, mymail), uucp = NOTOK;
508 exit (status);
509 }
510 @
511
512
513 1.3
514 log
515 @LOCALE
516 putenv
517 @
518 text
519 @d3 1
520 a3 1
521 static char ident[] = "@@(#)$Id: umhook.c,v 1.2 1992/02/03 16:37:06 jromine Exp jromine $";
522 d62 1
523 a62 1
524 long lseek ();
525 d229 2
526 a230 2
527 if (lseek (uucp, (long) offset, 0) == (long) NOTOK)
528 adios (mymail, "unable to position to %ld offset on", offset);
529 d269 1
530 a269 1
531 (void) lseek (td2, 0L, 0);
532 d322 1
533 a322 1
534 (void) lseek (fd2, 0L, 0);
535 d332 1
536 a332 1
537 (void) lseek (fd2, 0L, 0);
538 d444 1
539 a444 1
540 (void) lseek (fd, 0L, 0);
541 @
542
543
544 1.2
545 log
546 @fix
547 @
548 text
549 @d3 1
550 a3 1
551 static char ident[] = "@@(#)$Id: scan.c,v 1.10 1992/01/31 22:26:24 jromine Exp $";
552 d30 3
553 d84 3
554 d129 3
555 a131 3
556 (void) putenv ("USER", pw -> pw_name);
557 (void) putenv ("HOME", pw -> pw_dir);
558 (void) putenv ("SHELL", pw -> pw_shell);
559 @
560
561
562 1.1
563 log
564 @Initial revision
565 @
566 text
567 @d2 3
568 d61 1
569 d63 1
570 @