|
|
1.1 ! root 1: /* pipe.c - fred talks to dish */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/pipe.c,v 7.6 90/07/27 08:45:26 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/others/quipu/uips/fred/RCS/pipe.c,v 7.6 90/07/27 08:45:26 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: pipe.c,v $ ! 12: * Revision 7.6 90/07/27 08:45:26 mrose ! 13: * update ! 14: * ! 15: * Revision 7.5 90/06/11 21:17:10 mrose ! 16: * touch-up ! 17: * ! 18: * Revision 7.4 90/06/11 10:55:32 mrose ! 19: * UFN ! 20: * ! 21: * Revision 7.3 90/01/16 20:43:41 mrose ! 22: * last check-out ! 23: * ! 24: * Revision 7.2 90/01/11 18:36:39 mrose ! 25: * real-sync ! 26: * ! 27: * Revision 7.1 89/12/13 20:01:51 mrose ! 28: * errfp ! 29: * ! 30: * Revision 7.0 89/11/23 22:09:03 mrose ! 31: * Release 6.0 ! 32: * ! 33: */ ! 34: ! 35: /* ! 36: * NOTICE ! 37: * ! 38: * Acquisition, use, and distribution of this module and related ! 39: * materials are subject to the restrictions of a license agreement. ! 40: * Consult the Preface in the User's Manual for the full terms of ! 41: * this agreement. ! 42: * ! 43: */ ! 44: ! 45: ! 46: #include <signal.h> ! 47: #include "fred.h" ! 48: #include "internet.h" ! 49: ! 50: #include <sys/ioctl.h> ! 51: #ifndef SYS5 ! 52: #include <sys/file.h> ! 53: #else ! 54: #if !defined(AIX) && !defined(HPUX) ! 55: #include <sys/fcntl.h> ! 56: #else ! 57: #include <fcntl.h> ! 58: #endif ! 59: #endif ! 60: #include <sys/stat.h> ! 61: #include "usr.dirent.h" ! 62: #ifdef BSD42 ! 63: #include <sys/wait.h> ! 64: #endif ! 65: ! 66: /* */ ! 67: ! 68: int didbind = 0; ! 69: int dontpage = 0; ! 70: ! 71: static int dish_running = NOTOK; ! 72: ! 73: static struct sockaddr_in sin; ! 74: ! 75: /* DISH */ ! 76: ! 77: int dish (command, silent) ! 78: char *command; ! 79: int silent; ! 80: { ! 81: int cc, ! 82: isarea, ! 83: isuser, ! 84: n, ! 85: sd, ! 86: status; ! 87: char buffer[BUFSIZ], ! 88: where[BUFSIZ]; ! 89: register struct sockaddr_in *sock = &sin; ! 90: FILE *fp; ! 91: ! 92: if (watch) { ! 93: fprintf (stderr, "%s\n", command); ! 94: (void) fflush (stderr); ! 95: } ! 96: ! 97: isarea = strncmp (command, "moveto -pwd", sizeof "moveto -pwd" - 1) ! 98: ? 0 : 1; ! 99: isuser = !isarea && strcmp (command, "squid -fred -user") == 0; ! 100: ! 101: if (dish_running != NOTOK && kill (dish_running, 0) == NOTOK) ! 102: dish_running = NOTOK; ! 103: ! 104: if (dish_running == NOTOK) { ! 105: int vecp; ! 106: char dishname[BUFSIZ], ! 107: *vec[10]; ! 108: static int very_first_time = 1; ! 109: ! 110: if (very_first_time) { ! 111: (void) unsetenv ("DISHPROC"); ! 112: (void) unsetenv ("DISHPARENT"); ! 113: ! 114: (void) strcpy (ufn_file, "/tmp/ufnrc.XXXXXX"); ! 115: (void) unlink (mktemp (ufn_file)); ! 116: (void) setenv ("UFNRC", ufn_file); ! 117: ! 118: very_first_time = 0; ! 119: } ! 120: ! 121: if (get_dish_sock (&sin, getpid ()) == NOTOK) ! 122: exit (1); ! 123: ! 124: (void) strcpy (dishname, _isodefile (isodebinpath, "dish")); ! 125: ! 126: fork_again: ; ! 127: switch (dish_running = vfork ()) { ! 128: case NOTOK: ! 129: adios ("fork", "unable to"); ! 130: /* NOT REACHED */ ! 131: ! 132: case OK: ! 133: if (ifd != NOTOK) ! 134: (void) close (ifd); ! 135: if (ofd != NOTOK) ! 136: (void) close (ofd); ! 137: vecp = 0; ! 138: vec[vecp++] = "dish"; ! 139: vec[vecp++] = "-pipe"; ! 140: vec[vecp++] = "-fast"; ! 141: vec[vecp] = NULL; ! 142: (void) execv (dishname, vec); ! 143: fprintf (stderr, "unable to exec "); ! 144: perror (dishname); ! 145: _exit (1); ! 146: ! 147: default: ! 148: for (;;) { ! 149: if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) ! 150: == NOTOK) ! 151: adios ("client", "unable to start"); ! 152: if (join_tcp_server (sd, sock) != NOTOK) ! 153: break; ! 154: ! 155: (void) close_tcp_socket (sd); ! 156: ! 157: sleep (5); ! 158: ! 159: if (kill (dish_running, 0) == NOTOK) ! 160: goto fork_again; ! 161: } ! 162: didbind = 0; ! 163: (void) signal (SIGPIPE, SIG_IGN); ! 164: break; ! 165: } ! 166: } ! 167: else { ! 168: if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) ! 169: adios ("client", "unable to start"); ! 170: if (join_tcp_server (sd, sock) == NOTOK) ! 171: adios ("server", "unable to join"); ! 172: } ! 173: ! 174: n = send (sd, command, cc = strlen (command), 0); ! 175: if (debug) ! 176: fprintf (stderr, "wrote %d of %d octets to DUA\n", n, cc); ! 177: ! 178: if (n != cc) ! 179: if (n == NOTOK) { ! 180: advise ("please retry", "write to DUA failed,"); ! 181: (void) f_quit (NULLVP); ! 182: (void) close_tcp_socket (sd); ! 183: return NOTOK; ! 184: } ! 185: else ! 186: adios (NULLCP, "write to DUA truncated, sent %d of %d octets", ! 187: n, cc); ! 188: ! 189: status = OK; ! 190: for (;;) { ! 191: if ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) == NOTOK) { ! 192: if (!interrupted) ! 193: adios ("failed", "read from DUA"); ! 194: ! 195: (void) kill (dish_running, SIGINT); ! 196: interrupted = 0; ! 197: continue; ! 198: } ! 199: ! 200: buffer[cc] = NULL; ! 201: if (debug) ! 202: fprintf (stderr, "read %d octets from DUA: 0x%x\n", cc, buffer[0]); ! 203: if (cc == OK) { ! 204: if (kill (dish_running, 0) == NOTOK) ! 205: advise (NULLCP, "lost DUA"); ! 206: ! 207: break; ! 208: } ! 209: ! 210: switch (buffer[0]) { ! 211: case '2': ! 212: if ((fp = errfp) == NULL) ! 213: fp = stdfp != stdout ? stdfp : stderr; ! 214: status = NOTOK; ! 215: ! 216: copy_out: ; ! 217: if (cc > 1 && !silent) ! 218: paginate (fp, buffer + 1, cc - 1); ! 219: ! 220: while ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) > OK) ! 221: if (!silent) ! 222: paginate (fp, buffer, cc); ! 223: ! 224: if (!silent) ! 225: paginate (fp, NULLCP, 0); ! 226: break; ! 227: ! 228: case '1': ! 229: case '3': ! 230: if (isarea || isuser) { ! 231: char *cp, ! 232: **vp; ! 233: ! 234: if (cp = index (buffer + 1, '\n')) ! 235: *cp = NULL; ! 236: #ifdef notdef ! 237: if (buffer[1] == NULL) ! 238: break; ! 239: #endif ! 240: buffer[0] = '@'; ! 241: vp = isarea ? &myarea : &mydn; ! 242: ! 243: if (*vp) ! 244: free (*vp); ! 245: *vp = strdup (buffer); ! 246: } ! 247: fp = stdfp; ! 248: goto copy_out; ! 249: ! 250: case 'e': ! 251: if (watch) { ! 252: fprintf (stderr, "%s\n", buffer + 1); ! 253: (void) fflush (stderr); ! 254: } ! 255: if (system (buffer + 1)) ! 256: (void) strcpy (where, "e"); ! 257: else ! 258: (void) getcwd (where, sizeof where); ! 259: goto stuff_it; ! 260: ! 261: case 'y': ! 262: if (network) ! 263: (void) strcpy (where, "n"); ! 264: else { ! 265: fprintf (stderr, "%s", buffer + 1); ! 266: (void) fflush (stderr); ! 267: (void) fgets (where, sizeof where, stdin); ! 268: } ! 269: goto stuff_it; ! 270: ! 271: case 'p': ! 272: (void) sprintf (where, "Enter password for \"%s\": ", ! 273: buffer + 1); ! 274: (void) strcpy (where, getpassword (where)); ! 275: ! 276: stuff_it: ; ! 277: n = send (sd, where, cc = strlen (where), 0); ! 278: if (debug) ! 279: fprintf (stderr, "wrote %d of %d octets to DUA\n", n, cc); ! 280: ! 281: if (n != cc) ! 282: if (n == NOTOK) { ! 283: advise ("please retry", "write to DUA failed,"); ! 284: (void) f_quit (NULLVP); ! 285: (void) close_tcp_socket (sd); ! 286: return NOTOK; ! 287: } ! 288: else ! 289: adios (NULLCP, ! 290: "write to DUA truncated, sent %d of %d octets", ! 291: n, cc); ! 292: continue; ! 293: ! 294: default: ! 295: advise (NULLCP, "unexpected opcode 0x%x -- contact a camayoc", ! 296: buffer[0]); ! 297: break; ! 298: } ! 299: break; ! 300: } ! 301: ! 302: (void) close_tcp_socket (sd); ! 303: ! 304: return status; ! 305: } ! 306: ! 307: /* */ ! 308: ! 309: paginate (fp, buffer, cc) ! 310: FILE *fp; ! 311: char *buffer; ! 312: int cc; ! 313: { ! 314: static int first_time = 1; ! 315: static int doing_pager = 0; ! 316: static int pid = NOTOK; ! 317: static int sd = NOTOK; ! 318: static SFP istat, qstat; ! 319: ! 320: if (cc == 0) { ! 321: #ifndef BSD42 ! 322: int status; ! 323: #else ! 324: union wait status; ! 325: #endif ! 326: int child; ! 327: ! 328: first_time = 1; ! 329: (void) fflush (fp); ! 330: if (!doing_pager) ! 331: return; ! 332: ! 333: doing_pager = 0; ! 334: ! 335: if (dup2 (sd, fileno (fp)) == NOTOK) ! 336: adios ("standard output", "unable to dup2"); ! 337: ! 338: clearerr (fp); ! 339: (void) close (sd); ! 340: ! 341: while ((child = wait (&status)) != NOTOK && pid != child) ! 342: continue; ! 343: ! 344: (void) signal (SIGINT, istat); ! 345: (void) signal (SIGQUIT, qstat); ! 346: ! 347: return; ! 348: } ! 349: ! 350: if (first_time) { ! 351: int pd[2]; ! 352: ! 353: first_time = 0; ! 354: ! 355: if (dontpage || network || *pager == NULL || !isatty (fileno (fp))) ! 356: goto no_pager; ! 357: ! 358: (void) fflush (fp); ! 359: ! 360: foreground (); ! 361: ! 362: if ((sd = dup (fileno (fp))) == NOTOK) { ! 363: advise ("dup", "unable to"); ! 364: goto no_pager; ! 365: } ! 366: ! 367: if (pipe (pd) == NOTOK) { ! 368: advise ("pipe", "unable to"); ! 369: goto no_pager; ! 370: } ! 371: switch (pid = fork ()) { ! 372: case NOTOK: ! 373: advise ("fork", "unable to"); ! 374: (void) close (pd[0]); ! 375: (void) close (pd[1]); ! 376: goto no_pager; ! 377: ! 378: case OK: ! 379: (void) signal (SIGINT, SIG_DFL); ! 380: (void) signal (SIGQUIT, SIG_DFL); ! 381: ! 382: (void) close (pd[1]); ! 383: if (pd[0] != fileno (stdin)) { ! 384: (void) dup2 (pd[0], fileno (stdin)); ! 385: (void) close (pd[0]); ! 386: } ! 387: if (readonly) ! 388: mypager (stdin); ! 389: else { ! 390: execlp (pager, pager, NULLCP); ! 391: fprintf (stderr, "unable to exec "); ! 392: perror (pager); ! 393: } ! 394: _exit (-1); ! 395: ! 396: default: ! 397: (void) close (pd[0]); ! 398: if (pd[1] != fileno (fp)) { ! 399: (void) dup2 (pd[1], fileno (fp)); ! 400: (void) close (pd[1]); ! 401: } ! 402: break; ! 403: } ! 404: ! 405: istat = signal (SIGINT, SIG_IGN); ! 406: qstat = signal (SIGQUIT, SIG_IGN); ! 407: ! 408: doing_pager = 1; ! 409: } ! 410: ! 411: no_pager: ; ! 412: if (network && !mail) { ! 413: register char *cp, ! 414: *dp; ! 415: ! 416: for (dp = (cp = buffer) + cc; cp < dp; cp++) { ! 417: if (*cp == '\n') ! 418: (void) fputc ('\r', fp); ! 419: (void) fputc (*cp, fp); ! 420: } ! 421: } ! 422: else ! 423: (void) fwrite (buffer, sizeof buffer[0], cc, fp); ! 424: } ! 425: ! 426: /* */ ! 427: ! 428: /* if you start a fred command and then background fred, if your pager is less, ! 429: then for some reason, less gets the terminal modes/process groups messed up. ! 430: ! 431: this code pretty much ensures that fred is running in the foreground when ! 432: it forks less. there is still a critical window, but it is very small... ! 433: */ ! 434: ! 435: static foreground () { ! 436: #ifdef TIOCGPGRP ! 437: int pgrp, ! 438: tpgrp; ! 439: SFP tstat; ! 440: ! 441: if ((pgrp = getpgrp (0)) == NOTOK) ! 442: return; ! 443: ! 444: tstat = signal (SIGTTIN, SIG_DFL); ! 445: for (;;) { ! 446: if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK) ! 447: break; ! 448: if (pgrp == tpgrp) ! 449: break; ! 450: ! 451: (void) kill (0, SIGTTIN); ! 452: } ! 453: (void) signal (SIGTTIN, tstat); ! 454: #endif ! 455: } ! 456: ! 457: /* */ ! 458: ! 459: static int cols; ! 460: static int rows; ! 461: static int length = 0; ! 462: static int width = 0; ! 463: ! 464: ! 465: static mypager (fp) ! 466: FILE *fp; ! 467: { ! 468: register char *bp; ! 469: char buffer[BUFSIZ]; ! 470: #ifdef TIOCGWINSZ ! 471: struct winsize ws; ! 472: #endif ! 473: ! 474: #ifdef TIOCGWINSZ ! 475: if (ioctl (fileno (stdout), TIOCGWINSZ, (char *) &ws) != NOTOK) ! 476: length = ws.ws_row, width = ws.ws_col; ! 477: #endif ! 478: if (--length <= 0) ! 479: length = 23; ! 480: if (--width <= 0) ! 481: width = 79; ! 482: ! 483: rows = cols = 0; ! 484: ! 485: while (fgets (buffer, sizeof buffer, fp)) ! 486: for (bp = buffer; *bp; bp++) ! 487: pagchar (*bp); ! 488: ! 489: (void) fflush (stdout); ! 490: } ! 491: ! 492: ! 493: static pagchar (ch) ! 494: char ch; ! 495: { ! 496: char buffer[BUFSIZ]; ! 497: ! 498: switch (ch) { ! 499: case '\n': ! 500: cols = 0; ! 501: if (++rows < length) ! 502: break; ! 503: (void) putc (0x07, stdout); ! 504: (void) fflush (stdout); ! 505: buffer[0] = NULL; ! 506: (void) read (fileno (stdout), buffer, sizeof buffer); ! 507: if (buffer[0] == '\n') ! 508: rows = 0; ! 509: else { ! 510: (void) putc ('\n', stdout); ! 511: rows = length / 3; ! 512: } ! 513: return; ! 514: ! 515: case '\t': ! 516: cols |= 07; ! 517: cols++; ! 518: break; ! 519: ! 520: case '\b': ! 521: cols--; ! 522: break; ! 523: ! 524: case '\r': ! 525: cols = 0; ! 526: break; ! 527: ! 528: default: ! 529: if (ch >= ' ') ! 530: cols++; ! 531: break; ! 532: } ! 533: ! 534: if (cols >= width) { ! 535: pagchar ('\n'); ! 536: pagchar (ch); ! 537: } ! 538: else ! 539: (void) putc (ch, stdout); ! 540: } ! 541: ! 542: /* BIND */ ! 543: ! 544: /* ARGSUSED */ ! 545: ! 546: int f_bind (vec) ! 547: char **vec; ! 548: { ! 549: if (didbind) { ! 550: didbind = 0; ! 551: return OK; ! 552: } ! 553: ! 554: #ifdef notdef ! 555: if (dish_running == NOTOK || kill (dish_running, 0) == NOTOK) ! 556: return dish ("bind", 0); ! 557: ! 558: return OK; ! 559: #else ! 560: return dish ("bind", 0); ! 561: #endif ! 562: } ! 563: ! 564: /* ARGSUSED */ ! 565: ! 566: /* QUIT */ ! 567: ! 568: int f_quit (vec) ! 569: char **vec; ! 570: { ! 571: if (vec && *++vec != NULL && strcmp (*vec, "-help") == 0) { ! 572: fprintf (stdfp, "quit\n"); ! 573: fprintf (stdfp, " terminate fred\n"); ! 574: ! 575: return OK; ! 576: } ! 577: ! 578: if (dish_running != NOTOK) { ! 579: (void) kill (dish_running, SIGHUP); ! 580: ! 581: dish_running = NOTOK; ! 582: } ! 583: ! 584: if (ufn_file[0]) ! 585: (void) unlink (ufn_file); ! 586: ! 587: return DONE; ! 588: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.