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