pipe.c

来自「ftam等标准协议服务器和客户端的源代码。」· C语言 代码 · 共 1,154 行 · 第 1/2 页

C
1,154
字号
/* pipe.c - fred talks to dish */#ifndef	lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/quipu/uips/fred/RCS/pipe.c,v 9.0 1992/06/16 12:44:30 isode Rel $";#endif/*  * $Header: /xtel/isode/isode/others/quipu/uips/fred/RCS/pipe.c,v 9.0 1992/06/16 12:44:30 isode Rel $ * * * $Log: pipe.c,v $ * Revision 9.0  1992/06/16  12:44:30  isode * Release 8.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 <ctype.h>#include <signal.h>#include <varargs.h>#include "fred.h"#include "internet.h"#include "sys.file.h"#include <sys/stat.h>#include "usr.dirent.h"#ifdef	BSD42#include <sys/wait.h>#endif/*  */static int	dish_running = NOTOK;static struct sockaddr_in sin;static int	dafd = NOTOK;static char	da_reply[BUFSIZ];static	do_edit ();static  foreground ();static	mypager ();static pagchar ();#ifndef	lintstatic int  da_command ();static int  _da_command ();#endifstatic int  da_response ();/*    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) {	(void) 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 (dafd != NOTOK) {	if (da_command ("STAT") == NOTOK) {	    (void) close_tcp_socket (dafd);	    dafd = NOTOK, boundP = 0;	}    }    else	if (dish_running != NOTOK	    && kill (dish_running, 0) == NOTOK)	dish_running = NOTOK, boundP = 0;    if (dish_running == NOTOK && dafd == NOTOK) {	int	vecp;	char	dishname[BUFSIZ],	       *vec[4];	static int very_first_time = 1;	if (very_first_time) {	    (void) unsetenv ("DISHPROC");	    (void) unsetenv ("DISHPARENT");	    very_first_time = 0;	}	if (strcmp (server, "internal")) {	    int	    portno;	    char   *cp,		   *dp;	    register struct hostent *hp;	    register struct servent *sp;	    if ((dafd = start_tcp_client ((struct sockaddr_in *) 0, 0))		    == NOTOK)		adios ("control connection", "unable to start");	    if (cp = index (server, ':')) {		if (sscanf (cp + 1, "%d", &portno) == 1)		    *cp = NULL;		else		    cp = NULL;	    }	    if ((hp = gethostbystring (server)) == NULL)		adios (NULLCP,		       "%s: unknown host for directory assistance server",		       server);	    if (cp)		*cp = ':';	    bzero ((char *) sock, sizeof *sock);	    sock -> sin_family = hp -> h_addrtype;	    inaddr_copy (hp, sock);	    if (cp)		sock -> sin_port = htons ((u_short) portno);	    else		if ((sp = getservbyname ("da", "tcp")) == NULL)		    sock -> sin_port = htons ((u_short) 411);		else		    sock -> sin_port = sp -> s_port;	    if (join_tcp_server (dafd, sock) == NOTOK)		adios ("control connection", "unable to establish");	    	    if (da_response () == NOTOK)		adios (NULLCP, "%s", da_reply);	    cp = da_reply + sizeof "+OK " - 1;	    if ((dp = index (cp, ' ')) == NULLCP		    || sscanf (dp + 1, "%d", &portno) != 1)		adios (NULLCP, "malformed response for data connection: %s",		       da_reply);	    *dp = NULL;	    if ((hp = gethostbystring (cp)) == NULL)		adios (NULLCP, "%s: unknown host for data connection", cp);	    bzero ((char *) sock, sizeof *sock);	    sock -> sin_family = hp -> h_addrtype;	    inaddr_copy (hp, sock);	    sock -> sin_port = htons ((u_short) portno);	    didbind = 0, boundP = 1;	    (void) signal (SIGPIPE, SIG_IGN);	    if (cp = getenv ("DISPLAY")) {		char cp_host [1024];		char *cp_disp;		struct sockaddr_in sinl;		int sinl_size;		(void) strncpy (cp_host, cp, 1024);		cp_host [1023] = '\0';		if ((cp_disp = index (cp_host, ':')) == NULLCP)		      goto no_display;		*cp_disp++ = '\0';		if (strcmp (cp_host, "local") && 		    strcmp (cp_host, "localhost") &&		    strcmp (cp_host, "unix"))		    (void) sprintf (buffer, "fred -display \"%s\"", cp);		else {		    sinl_size = sizeof (struct sockaddr_in);		    if (getsockname (dafd, (struct sockaddr *)&sinl, 				     &sinl_size) == NOTOK)			goto no_display;		    if (sinl.sin_addr.s_addr == sock->sin_addr.s_addr) 			(void) sprintf (buffer, "fred -display \"%s\"", cp);		    else {			cp = inet_ntoa (sinl.sin_addr);			(void) sprintf (buffer, "fred -display \"%s:%s\"",			    cp, cp_disp);		    }		}		(void) dish (buffer, 1);	    }no_display:	    goto do_conn;	}	if (get_dish_sock (sock, getpid (), 1) == 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:		vecp = 0;		vec[vecp++] = "dish";		vec[vecp++] = "-pipe";		vec[vecp++] = "-fast";		vec[vecp] = NULL;		(void) execv (dishname, vec);		(void) 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, boundP = 1;		(void) signal (SIGPIPE, SIG_IGN);		break;	}    }    else {do_conn: ;	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");    }    (void) sprintf (buffer, "%s\n", command);    n = send (sd, buffer, cc = strlen (buffer), 0);    if (debug)	(void) 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) {err_recv: ;	    if (!interrupted)		adios ("failed", "read from DUA");	    if (dafd != NOTOK)		(void) da_command ("INTR");	    else		(void) kill (dish_running, SIGINT);	    interrupted = 0;	    continue;	}	buffer[cc] = NULL;	if (debug)	    (void) fprintf (stderr, "read %d octets from DUA: '%c'\n", cc,		     cc > 0 ? buffer[0] : ' ');	if (cc == OK) {lost_dua: ;	    if ((dafd != NOTOK ? da_command ("STAT") : kill (dish_running, 0))		    == NOTOK) {		if (dafd != NOTOK) {		    (void) close_tcp_socket (dafd);		    dafd = NOTOK;		}		boundP = 0;		advise (NULLCP, "lost DUA");	    }	    break;	}	if (!isdigit (buffer[0])) {	    register char  *cp,			   *ep;	    cp = buffer + cc - 1;	    ep = buffer + sizeof buffer - 1;	    while (*cp != '\n') {		++cp;		switch (cc = recv (sd, cp, ep - cp, 0)) {		    case NOTOK:		        goto err_recv;		    case OK:		    default:			if (debug)			    (void) fprintf (stderr, "read %d more octets from DUA\n",				     cc);			if (cc == OK)			    goto lost_dua;		        cp += cc - 1;			if (cp < ep)			    continue;			if (debug)			    (void) fprintf (stderr,				     "'%c' directive exceeds %d octets",				     buffer[0], sizeof buffer - 1);			cp++;			break;		}		break;	    }	    *cp = NULL;	}	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) {		    (void) fprintf (stderr, "%s\n", buffer + 1);		    (void) fflush (stderr);		}		if (dafd != NOTOK)		    switch (do_edit (sd, buffer + 1)) {			case NOTOK:			    return NOTOK;			case OK:			    goto user_abort;			default:			    continue;		    }		if (system (buffer + 1)) {user_abort: ;		    (void) strcpy (where, "e");		}		else		    (void) getcwd (where, sizeof where);		goto stuff_it;	    case 'm':		(void) strcpy (where, "m");		if (!network) {		    (void) fprintf (stderr, "\n%s\n", buffer + 1);		    (void) fflush (stderr);		}		goto stuff_it;	    case 'y':		if (network)		    (void) strcpy (where, "n");		else		    switch (ask ("%s", buffer + 1)) {			case NOTOK:			default:			    (void) strcpy (where, "n");			    break;			case OK:			    (void) strcpy (where, "y");			    break;			case DONE:			    (void) putchar ('\n');			    (void) strcpy (where, "N");			    break;		    }		goto stuff_it;	    case 'p':		(void) sprintf (where, "Enter password for \"%s\": ",				buffer + 1);		(void) sprintf (where, "p%s", getpassword (where));stuff_it: ;		(void) strcat (where, "\n");		if (watch) {		    (void) fprintf (stderr, "%s", where);		    (void) fflush (stderr);		}		n = send (sd, where, cc = strlen (where), 0);		if (debug)		    (void) 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;}/*  */static	do_edit (sd, octets)int	sd;char   *octets;{    int	    cc,	    i,	    j,	    k,	    n;    char   *cp,	   *dp,	    buffer[BUFSIZ],	    tmpfil[BUFSIZ];    FILE   *fp;    struct stat st;    (void) strcpy (tmpfil, "/tmp/fredXXXXXX");    (void) unlink (mktemp (tmpfil));    if (sscanf (octets, "%d", &j) != 1 || j < 0) {	advise (NULLCP, "protocol botch");losing: ;	(void) f_quit (NULLVP);	(void) close_tcp_socket (sd);	(void) unlink (tmpfil);	return NOTOK;    }    if (watch) {	(void) fprintf (stderr, "y\n");	(void) fflush (stderr);    }    n = send (sd, "y\n", cc = sizeof "y\n" - 1, 0);    if (debug)	(void) 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,");	    goto losing;	}        else	    adios (NULLCP, "write to DUA truncated, sent %d of %d cotets",		   n, cc);    if ((fp = fopen (tmpfil, "w")) == NULL)	adios (tmpfil, "unable to write");    for (cc = j; j > 0; j -= i)	switch (i = recv (sd, buffer, j < sizeof buffer ? j : sizeof buffer,			  0)) {	    case NOTOK:		if (!interrupted)		    adios ("failed", "read from DUA");		(void) da_command ("INTR");		interrupted = 0;		(void) fclose (fp);		(void) unlink (tmpfil);		return DONE;	    case OK:		advise (NULLCP, "premature eof from peer");		goto losing;	    default:		if (debug)		    (void) fprintf (stderr, "read %d %soctets from DUA\n",			     i, j != cc ? "more " : "");		if (fp && fwrite (buffer, sizeof *buffer, i, fp) == 0) {		    advise (tmpfil, "error writing to");		    (void) fclose (fp);		    fp = NULL;		}		break;	}    if (fp == NULL) {all_done: ;	(void) unlink (tmpfil);	return OK;    }    (void) fclose (fp);    (void) sprintf (buffer, "%s %s",		    _isodefile (isodebinpath, "editentry"), tmpfil);    if (system (buffer))	goto all_done;    cp = NULL;    if ((fp = fopen (tmpfil, "r")) == NULL) {	advise ("reading", "unable to re-open %s for", tmpfil);	goto all_done;    }    if (fstat (fileno (fp), &st) == NOTOK	    || (st.st_mode & S_IFMT) != S_IFREG	    || (cc = st.st_size) == 0) {	advise (NULLCP, "%s: not a regular file", tmpfil);nearly_done: ;	if (cp)	    free (cp);	(void) fclose (fp);	goto all_done;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?