|
|
1.1 root 1: /* rcvtty.c - a rcvmail program (a lot like rcvalert) handling IPC ttys */
2:
3: #include "../h/mh.h"
4: #include "../h/rcvmail.h"
5: #include "../h/scansbr.h"
6: #include "../zotnet/tws.h"
7: #include <signal.h>
8: #include <sys/stat.h>
9: #ifndef TTYD
10: #include <utmp.h>
11: #endif not TTYD
12:
13: /* */
14:
15: static struct swit switches[] = {
16: #define HELPSW 0
17: "help", 4,
18:
19: NULL, NULL
20: };
21:
22: /* */
23:
24: static jmp_buf myctx;
25:
26: long lseek ();
27: char *getusr ();
28:
29: static int message_fd(), header_fd();
30: static void alert();
31:
32: /* */
33:
34: /* ARGSUSED */
35:
36: main(argc, argv)
37: int argc;
38: char **argv;
39: {
40: int md,
41: vecp = 0;
42: char *cp,
43: *user,
44: buf[100],
45: **ap,
46: **argp,
47: *arguments[MAXARGS],
48: *vec[MAXARGS];
49: #ifndef TTYD
50: char tty[BUFSIZ];
51: struct utmp ut;
52: register FILE *uf;
53: #endif not TTYD
54:
55: invo_name = r1bindex (argv[0], '/');
56: mts_init (invo_name);
57: if ((cp = m_find (invo_name)) != NULL) {
58: ap = brkstring (cp = getcpy (cp), " ", "\n");
59: ap = copyip (ap, arguments);
60: }
61: else
62: ap = arguments;
63: (void) copyip (argv + 1, ap);
64: argp = arguments;
65:
66: /* */
67:
68: while (cp = *argp++) {
69: if (*cp == '-')
70: switch (smatch (++cp, switches)) {
71: case AMBIGSW:
72: ambigsw (cp, switches);
73: done (1);
74: case UNKWNSW:
75: vec[vecp++] = --cp;
76: continue;
77: case HELPSW:
78: (void) sprintf (buf, "%s [command ...]", invo_name);
79: help (buf, switches);
80: done (1);
81: }
82: vec[vecp++] = cp;
83: }
84: vec[vecp] = 0;
85:
86: /* */
87:
88: if ((md = vecp ? message_fd (vec) : header_fd ()) == NOTOK)
89: exit (RCV_MBX);
90:
91: user = getusr ();
92: #ifndef TTYD
93: if ((uf = fopen ("/etc/utmp", "r")) == NULL)
94: exit (RCV_MBX);
95: while (fread ((char *) &ut, sizeof ut, 1, uf) == 1)
96: if (ut.ut_name[0] != NULL
97: && strncmp (user, ut.ut_name, sizeof ut.ut_name) == 0) {
98: (void) strncpy (tty, ut.ut_line, sizeof ut.ut_line);
99: alert (tty, md);
100: }
101: (void) fclose (uf);
102: #else TTYD
103: alert (user, md);
104: #endif TTYD
105:
106: exit (RCV_MOK);
107: }
108:
109: /* */
110:
111: /* ARGSUSED */
112:
113: static SIGDECL
114: alrmser(i)
115: int i;
116: {
117: longjmp (myctx, DONE);
118: }
119:
120:
121: static int
122: message_fd(vec)
123: char *vec[];
124: {
125: int bytes,
126: child_id,
127: fd;
128: char tmpfil[BUFSIZ];
129: struct stat st;
130:
131: (void) unlink (mktemp (strcpy (tmpfil, "/tmp/rcvttyXXXXX")));
132: if ((fd = creat (tmpfil, 0600)) == NOTOK)
133: return header_fd ();
134: (void) close (fd);
135:
136: if ((fd = open (tmpfil, 2)) == NOTOK)
137: return header_fd ();
138: (void) unlink (tmpfil);
139:
140: /* */
141:
142: switch (child_id = vfork ()) {
143: case NOTOK:
144: (void) close (fd);
145: return header_fd ();
146:
147: case OK:
148: rewind (stdin);
149: if (dup2 (fd, 1) == NOTOK || dup2 (fd, 2) == NOTOK)
150: _exit (-1);
151: closefds (3);
152: #ifdef BSD42
153: (void) setpgrp (0, getpid ());
154: #endif BSD42
155: execvp (vec[0], vec);
156: _exit (-1);
157:
158: default:
159: switch (setjmp (myctx)) {
160: case OK:
161: (void) signal (SIGALRM, alrmser);
162: bytes = fstat (fileno (stdin), &st) != NOTOK
163: ? (int) st.st_size : 100;
164: if (bytes <= 0)
165: bytes = 100;
166: (void) alarm ((unsigned) (bytes * 60 + 300));
167:
168: (void) pidwait (child_id, OK);
169:
170: (void) alarm (0);
171: if (fstat (fd, &st) != NOTOK && st.st_size > 0L)
172: return fd;
173: (void) close (fd);
174: return header_fd ();
175:
176: default:
177: #ifndef BSD42
178: (void) kill (child_id, SIGKILL);
179: #else BSD42
180: (void) killpg (child_id, SIGKILL);
181: #endif BSD42
182: (void) close (fd);
183: return header_fd ();
184: }
185: }
186: }
187:
188: /* */
189:
190: static int
191: header_fd()
192: {
193: int fd;
194: char tmpfil[BUFSIZ];
195:
196: (void) strcpy (tmpfil, m_tmpfil (invo_name));
197: if ((fd = creat (tmpfil, 0600)) == NOTOK)
198: return NOTOK;
199: (void) close (fd);
200:
201: if ((fd = open (tmpfil, 2)) == NOTOK)
202: return NOTOK;
203: (void) unlink (tmpfil);
204:
205: rewind (stdin);
206: (void) scan(stdin, 0, 0, NULLVP, 0, 0, 0, 0L, 0, 0);
207: (void) write(fd, scanl, strlen (scanl));
208:
209: return fd;
210: }
211:
212: /* */
213:
214: #ifndef TTYD
215: static void
216: alert(tty, md)
217: register char *tty;
218: int md;
219: {
220: int i,
221: td;
222: char buffer[BUFSIZ],
223: ttyspec[BUFSIZ];
224: struct stat st;
225:
226: (void) sprintf (ttyspec, "/dev/%s", tty);
227: if (stat (ttyspec, &st) == NOTOK || (st.st_mode & 02) == 0)
228: return;
229:
230: switch (setjmp (myctx)) {
231: case OK:
232: (void) signal (SIGALRM, alrmser);
233: (void) alarm (2);
234: td = open (ttyspec, 1);
235: (void) alarm (0);
236: if (td == NOTOK)
237: return;
238: break;
239:
240: default:
241: (void) alarm (0);
242: return;
243: }
244:
245: (void) lseek (md, 0L, 0);
246:
247: while ((i = read (md, buffer, sizeof buffer)) > 0)
248: if (write (td, buffer, i) != i)
249: break;
250:
251: (void) close (td);
252: }
253: #else TTYD
254:
255: /* */
256:
257: static void
258: alert(user, md)
259: register char *user;
260: int md;
261: {
262: int i,
263: td;
264: char buffer[BUFSIZ];
265:
266: if ((td = ttyw ("notify", NULLCP, NULLCP, user)) == NOTOK)
267: return;
268: (void) signal (SIGPIPE, SIG_IGN);
269:
270: (void) lseek (md, 0L, 0);
271: while ((i = read (md, buffer, sizeof buffer)) > 0)
272: if (write (td, buffer, i) != i)
273: break;
274:
275: (void) close (td);
276: }
277: #endif TTYD
278:
279: /*
280: * XXX We need to force config.o to be linked in to get around
281: * library order problems
282: */
283: /* XXX don't bother if linking with the shared library */
284: #ifndef SHARED
285: static void
286: kludge()
287: {
288: (void)libpath((char *)0);
289: }
290: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.