Added all of the MH sources, including RCS files, in
[mmh] / docs / historical / mh-6.8.5 / uip / RCS / rcvtty.c,v
1 head    1.13;
2 access;
3 symbols;
4 locks; strict;
5 comment @ * @;
6
7
8 1.13
9 date    94.04.21.18.20.50;      author jromine; state Exp;
10 branches;
11 next    1.12;
12
13 1.12
14 date    93.08.25.17.27.27;      author jromine; state Exp;
15 branches;
16 next    1.11;
17
18 1.11
19 date    92.12.15.00.20.22;      author jromine; state Exp;
20 branches;
21 next    1.10;
22
23 1.10
24 date    92.11.04.00.57.54;      author jromine; state Exp;
25 branches;
26 next    1.9;
27
28 1.9
29 date    92.02.12.17.49.00;      author jromine; state Exp;
30 branches;
31 next    1.8;
32
33 1.8
34 date    92.02.05.07.26.30;      author jromine; state Exp;
35 branches;
36 next    1.7;
37
38 1.7
39 date    92.01.31.22.25.16;      author jromine; state Exp;
40 branches;
41 next    1.6;
42
43 1.6
44 date    90.11.05.13.05.54;      author mh;      state Exp;
45 branches;
46 next    1.5;
47
48 1.5
49 date    90.04.05.15.02.11;      author sources; state Exp;
50 branches;
51 next    1.4;
52
53 1.4
54 date    90.03.17.09.54.07;      author sources; state Exp;
55 branches;
56 next    1.3;
57
58 1.3
59 date    90.03.12.14.21.19;      author sources; state Exp;
60 branches;
61 next    1.2;
62
63 1.2
64 date    90.02.06.13.28.40;      author sources; state Exp;
65 branches;
66 next    1.1;
67
68 1.1
69 date    90.02.06.13.28.27;      author sources; state Exp;
70 branches;
71 next    ;
72
73
74 desc
75 @@
76
77
78 1.13
79 log
80 @update for scansbr.c -- overload {folder}.c_flags with hdrflg
81 @
82 text
83 @/* rcvtty.c - a rcvmail program (a lot like rcvalert) handling IPC ttys */
84 #ifndef lint
85 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.12 1993/08/25 17:27:27 jromine Exp jromine $";
86 #endif  /* lint */
87
88 #ifndef BSD42
89 #undef  TTYD
90 #endif
91 #include "../h/mh.h"
92 #include "../h/rcvmail.h"
93 #include "../h/scansbr.h"
94 #include "../zotnet/tws.h"
95 #include <signal.h>
96 #include <sys/stat.h>
97 #ifndef TTYD
98 #include <utmp.h>
99 #endif  /* not TTYD */
100 #ifdef LOCALE
101 #include        <locale.h>
102 #endif
103
104 /* \f */
105 #define SCANFMT \
106 "%2(hour{dtimenow}):%02(min{dtimenow}): %<(size)%5(size) %>%<{encrypted}E%>\
107 %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>%<(zero)%17(friendly{from})%>  \
108 %{subject}%<{body}<<%{body}>>%>"
109
110 static struct swit switches[] = {
111 #define HELPSW  0
112     "help", 4,
113
114 #define BIFFSW  1
115     "biff", 0,
116
117 #define FORMSW  2
118     "form formatfile", 0,
119 #define FMTSW   3
120     "format string", 5,
121
122 #define NLSW    4
123     "newline", 0,
124 #define NNLSW   5
125     "nonewline", 0,
126 #define BELSW   6
127     "bell", 0,
128 #define NBELSW  7
129     "nobell", 0,
130
131     NULL, 0
132 };
133
134 /* \f */
135
136 static  jmp_buf myctx;
137
138 off_t   lseek ();
139 char   *getusr ();
140
141 static int      message_fd(), header_fd();
142 static          alert();
143
144 static int bell = 1;
145 static int newline = 1;
146 static int biff = 0;
147 static char *form = NULL;
148 static char *format = NULL;
149
150 /* \f */
151
152 /* ARGSUSED */
153
154 main (argc, argv)
155 int     argc;
156 char   **argv;
157 {
158     int     md,
159             vecp = 0;
160     char   *cp,
161            *user,
162             buf[100],
163           **ap,
164           **argp,
165            *arguments[MAXARGS],
166            *vec[MAXARGS];
167 #ifndef TTYD
168     char    tty[BUFSIZ];
169     struct utmp ut;
170     register FILE  *uf;
171 #endif  /* not TTYD */
172
173 #ifdef LOCALE
174         setlocale(LC_ALL, "");
175 #endif
176     invo_name = r1bindex (argv[0], '/');
177     mts_init (invo_name);
178     if ((cp = m_find (invo_name)) != NULL) {
179         ap = brkstring (cp = getcpy (cp), " ", "\n");
180         ap = copyip (ap, arguments);
181     }
182     else
183         ap = arguments;
184     (void) copyip (argv + 1, ap);
185     argp = arguments;
186
187 /* \f */
188
189     while (cp = *argp++) {
190         if (*cp == '-')
191             switch (smatch (++cp, switches)) {
192                 case AMBIGSW: 
193                     ambigsw (cp, switches);
194                     done (1);
195                 case UNKWNSW: 
196                     vec[vecp++] = --cp;
197                     continue;
198                 case HELPSW: 
199                     (void) sprintf (buf, "%s [command ...]", invo_name);
200                     help (buf, switches);
201                     done (1);
202
203                 case BIFFSW:
204                     biff = 1;
205                     continue;
206
207                 case FORMSW: 
208                     if (!(form = *argp++) || *form == '-')
209                         adios (NULLCP, "missing argument to %s", argp[-2]);
210                     format = NULL;
211                     continue;
212                 case FMTSW: 
213                     if (!(format = *argp++) || *format == '-')
214                         adios (NULLCP, "missing argument to %s", argp[-2]);
215                     form = NULL;
216                     continue;
217
218                 case NLSW:
219                     newline = 1;
220                     continue;
221                 case NNLSW:
222                     newline = 0;
223                     continue;
224                 case BELSW:
225                     bell = 1;
226                     continue;
227                 case NBELSW:
228                     bell = 0;
229                     continue;
230
231             }
232         vec[vecp++] = cp;
233     }
234     vec[vecp] = 0;
235
236 /* \f */
237
238     if ((md = vecp ? message_fd (vec) : header_fd ()) == NOTOK)
239         exit (RCV_MBX);
240
241     user = getusr ();
242 #ifndef TTYD
243     if ((uf = fopen ("/etc/utmp", "r")) == NULL)
244         exit (RCV_MBX);
245     while (fread ((char *) &ut, sizeof ut, 1, uf) == 1)
246         if (ut.ut_name[0] != 0
247                 && strncmp (user, ut.ut_name, sizeof ut.ut_name) == 0) {
248             (void) strncpy (tty, ut.ut_line, sizeof ut.ut_line);
249             alert (tty, md);
250         }
251     (void) fclose (uf);
252 #else   /* TTYD */
253     alert (user, md);
254 #endif  /* TTYD */
255
256     exit (RCV_MOK);
257 }
258
259 /* \f */
260
261 /* ARGSUSED */
262
263 static  TYPESIG alrmser (i)
264 int     i;
265 {
266     longjmp (myctx, DONE);
267 }
268
269
270 static int  message_fd (vec)
271 char   *vec[];
272 {
273     int     bytes,
274             child_id,
275             fd;
276     char    tmpfil[BUFSIZ];
277     struct stat st;
278
279     (void) unlink (mktemp (strcpy (tmpfil, "/tmp/rcvttyXXXXX")));
280     if ((fd = creat (tmpfil, 0600)) == NOTOK)
281         return header_fd ();
282     (void) close (fd);
283
284     if ((fd = open (tmpfil, 2)) == NOTOK)
285         return header_fd ();
286     (void) unlink (tmpfil);
287
288 /* \f */
289
290     switch (child_id = vfork ()) {
291         case NOTOK: 
292             (void) close (fd);
293             return header_fd ();
294
295         case OK: 
296             rewind (stdin);
297             if (dup2 (fd, 1) == NOTOK || dup2 (fd, 2) == NOTOK)
298                 _exit (-1);
299             closefds (3);
300 #ifdef  BSD42
301             (void) setpgrp (0, getpid ());
302 #endif  /* BSD42 */
303             execvp (vec[0], vec);
304             _exit (-1);
305
306         default: 
307             switch (setjmp (myctx)) {
308                 case OK: 
309                     (void) signal (SIGALRM, alrmser);
310                     bytes = fstat (fileno (stdin), &st) != NOTOK
311                         ? (int) st.st_size : 100;
312                     if (bytes <= 0)
313                         bytes = 100;
314                     (void) alarm ((unsigned) (bytes * 60 + 300));
315
316                     (void) pidwait (child_id, OK);
317
318                     (void) alarm (0);
319                     if (fstat (fd, &st) != NOTOK && st.st_size > (off_t)0)
320                         return fd;
321                     (void) close (fd);
322                     return header_fd ();
323
324                 default: 
325 #ifndef BSD42
326                     (void) kill (child_id, SIGKILL);
327 #else   /* BSD42 */
328                     (void) killpg (child_id, SIGKILL);
329 #endif  /* BSD42 */
330                     (void) close (fd);
331                     return header_fd ();
332             }
333     }
334 }
335
336 /* \f */
337
338 static int  header_fd () {
339     int     fd;
340     char    tmpfil[BUFSIZ];
341
342     (void) strcpy (tmpfil, m_tmpfil (invo_name));
343     if ((fd = creat (tmpfil, 0600)) == NOTOK)
344         return NOTOK;
345     (void) close (fd);
346
347     if ((fd = open (tmpfil, 2)) == NOTOK)
348         return NOTOK;
349     (void) unlink (tmpfil);
350
351     rewind (stdin);
352     (void) scan (stdin, 0, 0, new_fs (form, format, SCANFMT), 0, 0, 0,
353             0, 0, 0L, 0);
354     if ( newline )
355         (void) write (fd, "\n\r", 2);
356     (void) write (fd, scanl, strlen (scanl));
357     if ( bell )
358         (void) write (fd, "\007", 1);
359
360     return fd;
361 }
362
363 /* \f */
364
365 #ifndef TTYD
366 static  alert (tty, md)
367 char   *tty;
368 int     md;
369 {
370     int     i,
371             td;
372     char    buffer[BUFSIZ],
373             ttyspec[BUFSIZ];
374     struct stat st;
375
376     (void) sprintf (ttyspec, "/dev/%s", tty);
377     if (stat (ttyspec, &st) == NOTOK ||
378         (st.st_mode & (biff ? S_IEXEC :
379 #ifdef  BSD43
380                        (S_IWRITE >> 3)
381 #else   /* BSD43 */
382                        02
383 #endif  /* BSD43 */
384                        )) == 0)
385         return;
386
387     switch (setjmp (myctx)) {
388         case OK: 
389             (void) signal (SIGALRM, alrmser);
390             (void) alarm (2);
391             td = open (ttyspec, 1);
392             (void) alarm (0);
393             if (td == NOTOK)
394                 return;
395             break;
396
397         default: 
398             (void) alarm (0);
399             return;
400     }
401
402     (void) lseek (md, (off_t)0, 0);
403
404     while ((i = read (md, buffer, sizeof buffer)) > 0)
405         if (write (td, buffer, i) != i)
406             break;
407
408     (void) close (td);
409 }
410 #else   /* TTYD */
411
412 /* \f */
413
414 static  alert (user, md)
415 register char   *user;
416 int     md;
417 {
418     int     i,
419             td;
420     char    buffer[BUFSIZ];
421
422     if ((td = ttyw ("notify", NULLCP, NULLCP, user)) == NOTOK)
423         return;
424     (void) signal (SIGPIPE, SIG_IGN);
425
426     (void) lseek (md, (off_t), 0);
427     while ((i = read (md, buffer, sizeof buffer)) > 0)
428         if (write (td, buffer, i) != i)
429             break;
430
431     (void) close (td);
432 }
433 #endif  /* TTYD */
434 @
435
436
437 1.12
438 log
439 @off_t fixes for BSD44
440 @
441 text
442 @d3 1
443 a3 1
444 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.11 1992/12/15 00:20:22 jromine Exp jromine $";
445 d270 2
446 a271 1
447     (void) scan (stdin, 0, 0, new_fs (form, format, SCANFMT), 0, 0, 0, 0, 0L, 0);
448 @
449
450
451 1.11
452 log
453 @endif sugar
454 @
455 text
456 @d3 1
457 a3 1
458 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.10 1992/11/04 00:57:54 jromine Exp jromine $";
459 d56 1
460 a56 1
461 long    lseek ();
462 d237 1
463 a237 1
464                     if (fstat (fd, &st) != NOTOK && st.st_size > 0L)
465 d319 1
466 a319 1
467     (void) lseek (md, 0L, 0);
468 d343 1
469 a343 1
470     (void) lseek (md, 0L, 0);
471 @
472
473
474 1.10
475 log
476 @LOCALE
477 TYPESIG
478 @
479 text
480 @d3 2
481 a4 2
482 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.9 1992/02/12 17:49:00 jromine Exp jromine $";
483 #endif  lint
484 d17 1
485 a17 1
486 #endif  not TTYD
487 d89 1
488 a89 1
489 #endif  not TTYD
490 d170 1
491 a170 1
492 #else   TTYD
493 d172 1
494 a172 1
495 #endif  TTYD
496 d220 1
497 a220 1
498 #endif  BSD42
499 d245 1
500 a245 1
501 #else   BSD42
502 d247 1
503 a247 1
504 #endif  BSD42
505 d327 1
506 a327 1
507 #else   TTYD
508 d350 1
509 a350 1
510 #endif  TTYD
511 @
512
513
514 1.9
515 log
516 @fix from/to output
517 @
518 text
519 @d3 1
520 a3 1
521 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.8 1992/02/05 07:26:30 jromine Exp jromine $";
522 d18 3
523 d91 3
524 d181 1
525 a181 1
526 static  int alrmser (i)
527 @
528
529
530 1.8
531 log
532 @put unseen sequence in mh-format
533 @
534 text
535 @d3 1
536 a3 1
537 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.7 1992/01/31 22:25:16 jromine Exp jromine $";
538 d22 1
539 a22 1
540 %<(mymbox{from})To:%14(friendly{to})%|%17(friendly{from})%>  \
541 @
542
543
544 1.7
545 log
546 @kerberos
547 @
548 text
549 @d3 1
550 a3 1
551 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.6 1990/11/05 13:05:54 mh Exp jromine $";
552 d264 1
553 a264 1
554     (void) scan (stdin, 0, 0, new_fs (form, format, SCANFMT), 0, 0, 0, 0L, 0);
555 @
556
557
558 1.6
559 log
560 @fix from author -- don't display size if zero
561 @
562 text
563 @d3 1
564 a3 1
565 static char ident[] = "@@(#)$Id: rcvtty.c,v 1.5 90/04/05 15:02:11 sources Exp Locker: mh $";
566 d46 1
567 a46 1
568     NULL, NULL
569 d158 1
570 a158 1
571         if (ut.ut_name[0] != NULL
572 @
573
574
575 1.5
576 log
577 @add ID
578 @
579 text
580 @d3 1
581 a3 1
582 static char ident[] = "@@(#)$Id:$";
583 d21 1
584 a21 1
585 "%2(hour{dtimenow}):%02(min{dtimenow}): %5(size) %<{encrypted}E%>\
586 @
587
588
589 1.4
590 log
591 @fixes from jeff honig
592 add {dtimenow} to scansbr
593 add a bunch of options to rcvtty
594 @
595 text
596 @d2 3
597 @
598
599
600 1.3
601 log
602 @check group write on tty under BSD43
603 @
604 text
605 @d17 4
606 d26 17
607 d55 7
608 d111 29
609 d261 3
610 a263 1
611     (void) scan (stdin, 0, 0, NULLCP, 0, 0, 0, 0L, 0);
612 d265 2
613 d285 8
614 a292 7
615     if (stat (ttyspec, &st) == NOTOK || 
616 #ifndef BSD43
617             (st.st_mode & 02) == 0
618 #else   BSD43
619             (st.st_mode & (S_IWRITE >> 3)) == 0         /* group permissions */
620 #endif  BSD43
621             )
622 @
623
624
625 1.2
626 log
627 @ANSI Compilance
628 @
629 text
630 @d224 7
631 a230 1
632     if (stat (ttyspec, &st) == NOTOK || (st.st_mode & 02) == 0)
633 @
634
635
636 1.1
637 log
638 @Initial revision
639 @
640 text
641 @d32 2
642 @