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 + -
显示快捷键?