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