|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 10770 (0x2a12) Types: TextFile Names: »pipe.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/others/quipu/uips/fred/pipe.c«
/* pipe.c - fred talks to dish */ #ifndef lint static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/pipe.c,v 7.3 90/01/16 20:43:41 mrose Exp $"; #endif /* * $Header: /f/osi/others/quipu/uips/fred/RCS/pipe.c,v 7.3 90/01/16 20:43:41 mrose Exp $ * * * $Log: pipe.c,v $ * Revision 7.3 90/01/16 20:43:41 mrose * last check-out * * Revision 7.2 90/01/11 18:36:39 mrose * real-sync * * Revision 7.1 89/12/13 20:01:51 mrose * errfp * * Revision 7.0 89/11/23 22:09:03 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ #include <signal.h> #include "fred.h" #include "internet.h" #include <sys/ioctl.h> #ifndef SYS5 #include <sys/file.h> #else #if !defined(AIX) && !defined(HPUX) #include <sys/fcntl.h> #else #include <fcntl.h> #endif #endif #include <sys/stat.h> #include "usr.dirent.h" #ifdef BSD42 #include <sys/wait.h> #endif /* \f */ int didbind = 0; int dontpage = 0; static int dish_running = NOTOK; static struct sockaddr_in sin; /* \f DISH */ int dish (command, silent) char *command; int silent; { int cc, isarea, isuser, n, sd, status; char buffer[BUFSIZ], where[BUFSIZ]; register struct sockaddr_in *sock = &sin; FILE *fp; if (watch) { fprintf (stderr, "%s\n", command); (void) fflush (stderr); } isarea = strncmp (command, "moveto -pwd", sizeof "moveto -pwd" - 1) ? 0 : 1; isuser = !isarea && strcmp (command, "squid -user") == 0; if (dish_running != NOTOK && kill (dish_running, 0) == NOTOK) dish_running = NOTOK; if (dish_running == NOTOK) { int vecp; char dishname[BUFSIZ], *vec[10]; static int very_first_time = 1; if (very_first_time) { (void) unsetenv ("DISHPROC"); (void) unsetenv ("DISHPARENT"); very_first_time = 0; } if (get_dish_sock (&sin, getpid ()) == NOTOK) exit (1); (void) strcpy (dishname, _isodefile (isodebinpath, "dish")); fork_again: ; switch (dish_running = vfork ()) { case NOTOK: adios ("fork", "unable to"); /* NOT REACHED */ case OK: if (ifd != NOTOK) (void) close (ifd); if (ofd != NOTOK) (void) close (ofd); vecp = 0; vec[vecp++] = "dish"; vec[vecp++] = "-pipe"; vec[vecp++] = "-fast"; vec[vecp] = NULL; (void) execv (dishname, vec); fprintf (stderr, "unable to exec "); perror (dishname); _exit (1); default: for (;;) { if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) adios ("client", "unable to start"); if (join_tcp_server (sd, sock) != NOTOK) break; (void) close_tcp_socket (sd); sleep (5); if (kill (dish_running, 0) == NOTOK) goto fork_again; } didbind = 0; (void) signal (SIGPIPE, SIG_IGN); break; } } else { if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK) adios ("client", "unable to start"); if (join_tcp_server (sd, sock) == NOTOK) adios ("server", "unable to join"); } n = send (sd, command, cc = strlen (command), 0); if (debug) fprintf (stderr, "wrote %d of %d octets to DUA\n", n, cc); if (n != cc) if (n == NOTOK) { advise ("please retry", "write to DUA failed,"); (void) f_quit (NULLVP); (void) close_tcp_socket (sd); return NOTOK; } else adios (NULLCP, "write to DUA truncated, sent %d of %d octets", n, cc); status = OK; for (;;) { if ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) == NOTOK) { if (!interrupted) adios ("failed", "read from DUA"); (void) kill (dish_running, SIGINT); interrupted = 0; continue; } buffer[cc] = NULL; if (debug) fprintf (stderr, "read %d octets from DUA: 0x%x\n", cc, buffer[0]); if (cc == OK) { if (kill (dish_running, 0) == NOTOK) advise (NULLCP, "lost DUA"); break; } switch (buffer[0]) { case '2': if ((fp = errfp) == NULL) fp = stdfp != stdout ? stdfp : stderr; status = NOTOK; copy_out: ; if (cc > 1 && !silent) paginate (fp, buffer + 1, cc - 1); while ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) > OK) if (!silent) paginate (fp, buffer, cc); if (!silent) paginate (fp, NULLCP, 0); break; case '1': case '3': if (isarea || isuser) { char *cp, **vp; if (cp = index (buffer + 1, '\n')) *cp = NULL; #ifdef notdef if (buffer[1] == NULL) break; #endif buffer[0] = '@'; vp = isarea ? &myarea : &mydn; if (*vp) free (*vp); *vp = strdup (buffer); } fp = stdfp; goto copy_out; case 'e': if (watch) { fprintf (stderr, "%s\n", buffer + 1); (void) fflush (stderr); } if (system (buffer + 1)) (void) strcpy (where, "e"); else (void) getcwd (where, sizeof where); goto stuff_it; case 'y': if (network) (void) strcpy (where, "n"); else { fprintf (stderr, "%s", buffer + 1); (void) fflush (stderr); (void) fgets (where, sizeof where, stdin); } goto stuff_it; case 'p': (void) sprintf (where, "Enter password for \"%s\": ", buffer + 1); (void) strcpy (where, getpassword (where)); stuff_it: ; n = send (sd, where, cc = strlen (where), 0); if (debug) fprintf (stderr, "wrote %d of %d octets to DUA\n", n, cc); if (n != cc) if (n == NOTOK) { advise ("please retry", "write to DUA failed,"); (void) f_quit (NULLVP); (void) close_tcp_socket (sd); return NOTOK; } else adios (NULLCP, "write to DUA truncated, sent %d of %d octets", n, cc); continue; default: advise (NULLCP, "unexpected opcode 0x%x -- contact a camayoc", buffer[0]); break; } break; } (void) close_tcp_socket (sd); return status; } /* \f */ paginate (fp, buffer, cc) FILE *fp; char *buffer; int cc; { static int first_time = 1; static int doing_pager = 0; static int pid = NOTOK; static int sd = NOTOK; static SFP istat, qstat; if (cc == 0) { #ifndef BSD42 int status; #else union wait status; #endif int child; first_time = 1; (void) fflush (fp); if (!doing_pager) return; doing_pager = 0; if (dup2 (sd, fileno (fp)) == NOTOK) adios ("standard output", "unable to dup2"); clearerr (fp); (void) close (sd); while ((child = wait (&status)) != NOTOK && pid != child) continue; (void) signal (SIGINT, istat); (void) signal (SIGQUIT, qstat); return; } if (first_time) { int pd[2]; first_time = 0; if (dontpage || network || *pager == NULL || !isatty (fileno (fp))) goto no_pager; (void) fflush (fp); foreground (); if ((sd = dup (fileno (fp))) == NOTOK) { advise ("dup", "unable to"); goto no_pager; } if (pipe (pd) == NOTOK) { advise ("pipe", "unable to"); goto no_pager; } switch (pid = fork ()) { case NOTOK: advise ("fork", "unable to"); (void) close (pd[0]); (void) close (pd[1]); goto no_pager; case OK: (void) signal (SIGINT, SIG_DFL); (void) signal (SIGQUIT, SIG_DFL); (void) close (pd[1]); if (pd[0] != fileno (stdin)) { (void) dup2 (pd[0], fileno (stdin)); (void) close (pd[0]); } if (readonly) mypager (stdin); else { execlp (pager, pager, NULLCP); fprintf (stderr, "unable to exec "); perror (pager); } _exit (-1); default: (void) close (pd[0]); if (pd[1] != fileno (fp)) { (void) dup2 (pd[1], fileno (fp)); (void) close (pd[1]); } break; } istat = signal (SIGINT, SIG_IGN); qstat = signal (SIGQUIT, SIG_IGN); doing_pager = 1; } no_pager: ; if (network && !mail) { register char *cp, *dp; for (dp = (cp = buffer) + cc; cp < dp; cp++) { if (*cp == '\n') (void) fputc ('\r', fp); (void) fputc (*cp, fp); } } else (void) fwrite (buffer, sizeof buffer[0], cc, fp); } /* \f */ /* if you start a fred command and then background fred, if your pager is less, then for some reason, less gets the terminal modes/process groups messed up. this code pretty much ensures that fred is running in the foreground when it forks less. there is still a critical window, but it is very small... */ static foreground () { #ifdef TIOCGPGRP int pgrp, tpgrp; SFP tstat; if ((pgrp = getpgrp (0)) == NOTOK) return; tstat = signal (SIGTTIN, SIG_DFL); for (;;) { if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK) break; if (pgrp == tpgrp) break; (void) kill (0, SIGTTIN); } (void) signal (SIGTTIN, tstat); #endif } /* \f */ static int cols; static int rows; static int length = 0; static int width = 0; static mypager (fp) FILE *fp; { register char *bp; char buffer[BUFSIZ]; #ifdef TIOCGWINSZ struct winsize ws; #endif #ifdef TIOCGWINSZ if (ioctl (fileno (stdout), TIOCGWINSZ, (char *) &ws) != NOTOK) length = ws.ws_row, width = ws.ws_col; #endif if (--length <= 0) length = 23; if (--width <= 0) width = 79; rows = cols = 0; while (fgets (buffer, sizeof buffer, fp)) for (bp = buffer; *bp; bp++) pagchar (*bp); (void) fflush (stdout); } static pagchar (ch) char ch; { char buffer[BUFSIZ]; switch (ch) { case '\n': cols = 0; if (++rows < length) break; (void) putc (0x07, stdout); (void) fflush (stdout); buffer[0] = NULL; (void) read (fileno (stdout), buffer, sizeof buffer); if (buffer[0] == '\n') rows = 0; else { (void) putc ('\n', stdout); rows = length / 3; } return; case '\t': cols |= 07; cols++; break; case '\b': cols--; break; case '\r': cols = 0; break; default: if (ch >= ' ') cols++; break; } if (cols >= width) { pagchar ('\n'); pagchar (ch); } else (void) putc (ch, stdout); } /* \f BIND */ /* ARGSUSED */ int f_bind (vec) char **vec; { if (didbind) { didbind = 0; return OK; } #ifdef notdef if (dish_running == NOTOK || kill (dish_running, 0) == NOTOK) return dish ("bind", 0); return OK; #else return dish ("bind", 0); #endif } /* ARGSUSED */ /* \f QUIT */ int f_quit (vec) char **vec; { if (vec && *++vec != NULL && strcmp (*vec, "-help") == 0) { fprintf (stdfp, "quit\n"); fprintf (stdfp, " terminate fred\n"); return OK; } if (dish_running != NOTOK) { (void) kill (dish_running, SIGHUP); dish_running = NOTOK; } return DONE; }