pipe.c

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

C
1,154
字号
    }    (void) sprintf (buffer, "e%d\n", cc);    j = strlen (buffer);    if ((cp = malloc ((unsigned) (k = cc + j + 1))) == NULL)	adios (NULLCP, "out of memory");    (void) strcpy (dp = cp, buffer);    for (dp += j, j = cc; j > 0; dp += i, j -= i)	switch (i = fread (dp, sizeof *dp, j, fp)) {	    case NOTOK:	        advise (tmpfil, "error reading");		goto nearly_done;	    case OK:		advise (NULLCP, "premature eof reading %s", tmpfil);		goto nearly_done;	    default:		break;	}    *dp = NULL;    (void) fclose (fp);    (void) unlink (tmpfil);    if (watch) {	(void) fprintf (stderr, "///////\n%s///////\n", cp);	(void) fflush (stderr);    }    for (dp = cp, j = k; j > 0; dp += i, j -= i)	switch (i = send (sd, dp, j, 0)) {	    case NOTOK:	        advise ("please retry", "write to DUA failed,");		(void) f_quit (NULLVP);		(void) close_tcp_socket (sd);		free (cp);		return NOTOK;	    case OK:		adios (NULLCP, "zero-length write to peer");	    default:		if (debug)		    (void) fprintf (stderr, "wrote %d %soctets to DUA\n",			     j, dp != cp ? "more " : "");	        break;	}        free (cp);    return DONE;}/*  */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) {#ifdef SVR4	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);#ifdef SVR4	while ((child = wait (&status)) != NOTOK#else	while ((child = wait (&status.w_status)) != NOTOK #endif		       && child != pid)	    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 {		    (void) execlp (pager, pager, NULLCP);		    (void) 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);}/*  *//* if you start a 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}/*  */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;	    if (bflag)		(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);}/*    BIND *//* ARGSUSED */int	f_bind (vec)char  **vec;{    if (didbind) {	didbind = 0;	return OK;    }    return dish ("bind", 0);}/*    QUIT */int	f_quit (vec)char  **vec;{    if (vec && *++vec != NULL && strcmp (*vec, "-help") == 0) {	(void) fprintf (stdfp, "quit\n");	(void) fprintf (stdfp, "    terminate fred\n");	return OK;    }    if (dafd != NOTOK) {	(void) da_command ("QUIT");	(void) close_tcp_socket (dafd);    }    else	if (dish_running != NOTOK)	    (void) kill (dish_running, SIGHUP);	dafd = dish_running = NOTOK, boundP = 0;        return DONE;}/*    DA */#ifndef	lintstatic int  da_command (va_alist)va_dcl{    int	    val;    va_list ap;    va_start (ap);    val = _da_command (ap);    va_end (ap);    return val;}static int  _da_command (ap)va_list ap;{    int	    cc,	    len;    char    buffer[BUFSIZ];    if (dafd == NOTOK)	return NOTOK;    _asprintf (buffer, NULLCP, ap);    if (watch) {	(void) fprintf (stderr, "<--- %s\n", buffer);	(void) fflush (stderr);    }    (void) strcat (buffer, "\r\n");    len = strlen (buffer);    if (write_tcp_socket (dafd, buffer, len) != len)	adios ("failed", "write_tcp_socket to control connection");    return (da_response ());}#else/* VARARGS1 */static int  da_command (fmt)char   *fmt;{    return da_command (fmt);}#endif/*  */static int  da_response (){    register char *cp,		  *ep;    for (ep = (cp = da_reply) + sizeof da_reply - 1; cp < ep;) {	if (read_tcp_socket (dafd, cp, sizeof *cp) != 1)	    adios ("control connection", "eof or error reading");	if (*cp++ == '\n')	    break;    }    *cp = NULL;    if (cp > da_reply)	cp--;    if (*cp == '\n') {	*cp = NULL;	if (cp > da_reply)	    cp--;    }    if (*cp == '\r')	*cp = NULL;    if (watch) {	(void) fprintf (stderr, "---> %s\n", da_reply);	(void) fflush (stderr);    }    switch (da_reply[0]) {	case '+':	    return OK;	case '-':	    return NOTOK;	default:	    adios (NULLCP, "unrecognized response");	    /* NOTREACHED */    }    }/*  */int	sync_ufnrc (){    register char *bp;    char    buffer[BUFSIZ];    register struct area_guide *ag;    (void) sprintf (bp = buffer, "fred -ufnrc");    bp += strlen (bp);    for (ag = areas; ag -> ag_record; ag++)	if (ag -> ag_record == W_ORGANIZATION)	    break;    (void) sprintf (bp, " 1 1 \"%s", myarea + 1);    bp += strlen (bp);    if ((ag -> ag_record) && (ag -> ag_area)) {	(void) sprintf (bp, "$%s", ag -> ag_area + 1);	bp += strlen (bp);    }    (void) sprintf (bp, "$-\"");    bp += strlen (bp);    (void) sprintf (bp, " 2 2 \"");    bp += strlen (bp);    if ((ag -> ag_record) && (ag -> ag_area)) {	(void) sprintf (bp, "%s$", ag -> ag_area + 1);	bp += strlen (bp);    }    (void) sprintf (bp, "%s$-\"", myarea + 1);    bp += strlen (bp);    (void) sprintf (bp, " 3 32767 \"-");    bp += strlen (bp);    if ((ag -> ag_record) && (ag->ag_area)) {	(void) sprintf (bp, "$%s", ag -> ag_area + 1);	bp += strlen (bp);    }    (void) sprintf (bp, "$%s\"", myarea + 1);    bp += strlen (bp);    return dish (buffer, 1);}/*  */int	init_ufnrc () {    register int   i;    int	    inprogress;    register char *bp,		  *cp,		  *ep;    char    buffer[BUFSIZ],	    sync[BUFSIZ],	    ufnrc[BUFSIZ];    FILE   *fp;    if (bp = getenv ("UFNRC"))	(void) strcpy (ufnrc, bp);    else {	if ((bp = getenv ("HOME")) == NULL)	    bp = ".";	(void) sprintf (ufnrc, "%s/.ufnrc", bp);    }    if ((fp = fopen (ufnrc, "r")) == NULL) {	(void) strcpy (ufnrc, isodefile ("ufnrc", 0));	if ((fp = fopen (ufnrc, "r")) == NULL)	    return NOTOK;    }    (void) sprintf (ep = sync, "fred -ufnrc");    ep += strlen (ep);    inprogress = 0;    for (i = 0; fgets (bp = buffer, sizeof buffer, fp); i++) {	if (*buffer == '#')	    continue;	if (bp = index (buffer, '\n'))	    *bp = NULL;	bp = buffer;	if (*bp == NULL) {	    if (inprogress) {		(void) strcpy (ep, "\"");		ep += strlen (ep);		inprogress = 0;	    }	    continue;	}	if (!isspace (*bp)) {	    int	    lower,		    upper;	    register char *dp;	    if ((cp = index (bp, ':')) == NULL) {		advise (NULLCP, "%s: missing ':' at line %d", ufnrc, i);		return NOTOK;	    }	    *cp++ = NULL;	    if (dp = index (bp, ',')) {		*dp++ = NULL;		while (isspace (*dp))		    dp++;		upper = *dp == '+' ? 32767 : atoi (dp);	    }	    else		upper = 0;	    lower = atoi (bp);	    (void) sprintf (ep, " %d %d \"", lower, upper ? upper : lower);	    ep += strlen (ep);	    bp = cp;	    inprogress = 1;	}	else	    if (!inprogress) {		advise (NULLCP, "%s: unexpected blank at start of line %d",			   ufnrc, i);		return NOTOK;	    }	    else		*ep++ = '$';	while (isspace (*bp))	    bp++;	(void) sprintf (ep, "%s", bp);	ep += strlen (ep);    }    if (inprogress) {	(void) strcpy (ep, "\"");	ep += strlen (ep);	inprogress = 0;    }    (void) fclose (fp);    return dish (sync, 1);}

⌨️ 快捷键说明

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