|
|
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;
}