This is cmds.c in view mode; [Download] [Up]
/* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that: (1) source distributions retain this entire copyright * notice and comment, and (2) distributions including binaries display * the following acknowledgement: ``This product includes software * developed by the University of California, Berkeley and its contributors'' * in the documentation or other materials provided with the distribution * and in all advertising materials mentioning features or use of this * software. Neither the name of the University nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "tip.h" #include "pathnames.h" #include <sys/file.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/types.h> #include <strings.h> /* * tip * * miscellaneous commands */ int creat(); int unlink(); void transfer(); void cu_take(); int args(); int kill(); int read(); int ioctl(); int write(); void prtime(); int close(); int pipe(); int fork(void); int wait(); int dup(); int dup2(); void execute(); void sendfile(); void transmit(); void send(); int sleep(); unsigned int alarm(); int vfork(); int execl(); int chdir(const char *path); int uu_unlock(); void vlex(char *s); void tandem(); int getpid(void); int anyof(); int quant[] = {60, 60, 24}; char null = '\0'; char *sep[] = {"second", "minute", "hour"}; static char *argv[10]; /* argument vector for take and put */ #ifdef HAYES extern int Cbaudrate; /* see hayes.c */ #endif void timeout(); /* timeout function called on alarm */ void stopsnd(); /* SIGINT handler during file transfers */ void intcopy(); /* interrupt routine for file transfers */ void disconnect(); /* * FTP - remote ==> local * get a file from the remote host */ void getfl(c) char c; { char buf[256], *cp, *expand(); putchar(c); /* * get the UNIX receiving file's name */ if (prompt("Local file name? ", copyname)) return; cp = expand(copyname); if ((sfd = creat(cp, 0666)) < 0) { printf("\r\n%s: cannot create\r\n", copyname); return; } /* * collect parameters */ if (prompt("List command for remote system? ", buf)) { unlink(copyname); return; } transfer(buf, sfd, value(EOFREAD)); } /* * Cu-like take command */ void cu_take(cc) char cc; { int fd, argc; char line[BUFSIZ], *expand(), *cp; if (prompt("[take] ", copyname)) return; if ((argc = args(copyname, argv)) < 1 || argc > 2) { printf("usage: <take> from [to]\r\n"); return; } if (argc == 1) argv[1] = argv[0]; cp = expand(argv[1]); if ((fd = creat(cp, 0666)) < 0) { printf("\r\n%s: cannot create\r\n", argv[1]); return; } sprintf(line, "cat %s;echo \01", argv[0]); transfer(line, fd, "\01"); } static jmp_buf intbuf; /* * Bulk transfer routine -- * used by getfl(), cu_take(), and pipefile() */ void transfer(buf, fd, eofchars) char *buf, *eofchars; int fd; { register int ct; char c, buffer[BUFSIZ]; char *p = buffer; register int cnt, eof; time_t start; void (*f)(); pwrite(FD, buf, size(buf)); quit = 0; kill(pid, SIGIOT); read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ /* * finish command */ pwrite(FD, "\r", 1); do read(FD, &c, 1); while ((c & 0177) != '\n'); ioctl(0, TIOCSETC, &defchars); setjmp(intbuf); f = signal(SIGINT, intcopy); start = time(0); for (ct = 0; !quit;) { eof = read(FD, &c, 1) <= 0; c &= 0177; if (quit) continue; if (eof || any(c, eofchars)) break; if (c == 0) continue; /* ignore nulls */ if (c == '\r') continue; *p++ = c; if (c == '\n' && boolean(value(VERBOSE))) printf("\r%d", ++ct); if ((cnt = (p - buffer)) == number(value(FRAMESIZE))) { if (write(fd, buffer, cnt) != cnt) { printf("\r\nwrite error\r\n"); quit = 1; } p = buffer; } } if (cnt = (p - buffer)) if (write(fd, buffer, cnt) != cnt) printf("\r\nwrite error\r\n"); if (boolean(value(VERBOSE))) prtime(" lines transferred in ", time(0) - start); ioctl(0, TIOCSETC, &tchars); write(fildes[1], (char *)&ccc, 1); signal(SIGINT, f); close(fd); } /* * FTP - remote ==> local process * send remote input to local process via pipe */ void pipefile() { int cpid, pdes[2]; char buf[256]; int status, p; if (prompt("Local command? ", buf)) return; if (pipe(pdes)) { printf("can't establish pipe\r\n"); return; } if ((cpid = fork()) < 0) { printf("can't fork!\r\n"); return; } else if (cpid) { if (prompt("List command for remote system? ", buf)) { close(pdes[0]), close(pdes[1]); kill(cpid, SIGKILL); } else { close(pdes[0]); signal(SIGPIPE, intcopy); transfer(buf, pdes[1], value(EOFREAD)); signal(SIGPIPE, SIG_DFL); while ((p = wait(&status)) > 0 && p != cpid); } } else { register int f; dup2(pdes[0], 0); close(pdes[0]); for (f = 3; f < 20; f++) close(f); execute(buf); printf("can't execl!\r\n"); exit(0); } } /* * Interrupt service routine for FTP */ void stopsnd() { stop = 1; signal(SIGINT, SIG_IGN); } /* * FTP - local ==> remote * send local file to remote host * terminate transmission with pseudo EOF sequence */ void sendfile(cc) char cc; { FILE *fd; char *fnamex; char *expand(); putchar(cc); /* * get file name */ if (prompt("Local file name? ", fname)) return; /* * look up file */ fnamex = expand(fname); if ((fd = fopen(fnamex, "r")) == NULL) { printf("%s: cannot open\r\n", fname); return; } transmit(fd, value(EOFWRITE), NULL); if (!boolean(value(ECHOCHECK))) { struct sgttyb buf; ioctl(FD, TIOCGETP, &buf); /* this does a */ ioctl(FD, TIOCSETP, &buf); /* wflushtty */ } } /* * Bulk transfer routine to remote host -- * used by sendfile() and cu_put() */ void transmit(fd, eofchars, command) FILE *fd; char *eofchars, *command; { char *pc, lastc; int c, ccount, lcount; time_t start_t, stop_t; void (*f)(); kill(pid, SIGIOT); /* put TIPOUT into a wait state */ stop = 0; f = signal(SIGINT, stopsnd); ioctl(0, TIOCSETC, &defchars); read(repdes[0], (char *)&ccc, 1); if (command != NULL) { for (pc = command; *pc; pc++) send(*pc); if (boolean(value(ECHOCHECK))) read(FD, (char *)&c, 1); /* trailing \n */ else { struct sgttyb buf; ioctl(FD, TIOCGETP, &buf); /* this does a */ ioctl(FD, TIOCSETP, &buf); /* wflushtty */ sleep(5); /* wait for remote stty to take effect */ } } lcount = 0; lastc = '\0'; start_t = time(0); while (1) { ccount = 0; do { c = getc(fd); if (stop) goto out; if (c == EOF) goto out; if (c == 0177 && !boolean(value(RAWFTP))) continue; lastc = c; if (c < 040) { if (c == '\n') { if (!boolean(value(RAWFTP))) c = '\r'; } else if (c == '\t') { if (!boolean(value(RAWFTP))) { if (boolean(value(TABEXPAND))) { send(' '); while ((++ccount % 8) != 0) send(' '); continue; } } } else if (!boolean(value(RAWFTP))) continue; } send(c); } while (c != '\r' && !boolean(value(RAWFTP))); if (boolean(value(VERBOSE))) printf("\r%d", ++lcount); if (boolean(value(ECHOCHECK))) { timedout = 0; alarm(value(ETIMEOUT)); do { /* wait for prompt */ read(FD, (char *)&c, 1); if (timedout || stop) { if (timedout) printf("\r\ntimed out at eol\r\n"); alarm(0); goto out; } } while ((c & 0177) != character(value(PROMPT))); alarm(0); } } out: if (lastc != '\n' && !boolean(value(RAWFTP))) send('\r'); for (pc = eofchars; *pc; pc++) send(*pc); stop_t = time(0); fclose(fd); signal(SIGINT, f); if (boolean(value(VERBOSE))) if (boolean(value(RAWFTP))) prtime(" chars transferred in ", stop_t - start_t); else prtime(" lines transferred in ", stop_t - start_t); write(fildes[1], (char *)&ccc, 1); ioctl(0, TIOCSETC, &tchars); } /* * Cu-like put command */ void cu_put(cc) char cc; { FILE *fd; char line[BUFSIZ]; int argc; char *expand(); char *copynamex; if (prompt("[put] ", copyname)) return; if ((argc = args(copyname, argv)) < 1 || argc > 2) { printf("usage: <put> from [to]\r\n"); return; } if (argc == 1) argv[1] = argv[0]; copynamex = expand(argv[0]); if ((fd = fopen(copynamex, "r")) == NULL) { printf("%s: cannot open\r\n", copynamex); return; } if (boolean(value(ECHOCHECK))) sprintf(line, "cat>%s\r", argv[1]); else sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); transmit(fd, "\04", line); } /* * FTP - send single character * wait for echo & handle timeout */ void send(c) char c; { char cc; int retry = 0; cc = c; pwrite(FD, &cc, 1); #ifdef notdef if (number(value(CDELAY)) > 0 && c != '\r') nap(number(value(CDELAY))); #endif if (!boolean(value(ECHOCHECK))) { #ifdef notdef if (number(value(LDELAY)) > 0 && c == '\r') nap(number(value(LDELAY))); #endif return; } tryagain: timedout = 0; alarm(value(ETIMEOUT)); read(FD, &cc, 1); alarm(0); if (timedout) { printf("\r\ntimeout error (%s)\r\n", ctrl(c)); if (retry++ > 3) return; pwrite(FD, &null, 1); /* poke it */ goto tryagain; } } void timeout() { signal(SIGALRM, timeout); timedout = 1; } /* * Stolen from consh() -- puts a remote file on the output of a local command. * Identical to consh() except for where stdout goes. */ void pipeout(char c) { char buf[256]; int cpid, status, p; time_t start=0; putchar(c); if (prompt("Local command? ", buf)) return; kill(pid, SIGIOT); /* put TIPOUT into a wait state */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); ioctl(0, TIOCSETC, &defchars); read(repdes[0], (char *)&ccc, 1); /* * Set up file descriptors in the child and let it go... */ if ((cpid = fork()) < 0) printf("can't fork!\r\n"); else if (cpid) { start = time(0); while ((p = wait(&status)) > 0 && p != cpid); } else { register int i; dup2(FD, 1); for (i = 3; i < 20; i++) close(i); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); execute(buf); printf("can't find `%s'\r\n", buf); exit(0); } if (boolean(value(VERBOSE))) prtime("away for ", time(0) - start); write(fildes[1], (char *)&ccc, 1); ioctl(0, TIOCSETC, &tchars); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); } #ifdef CONNECT /* * Fork a program with: * 0 <-> local tty in * 1 <-> local tty out * 2 <-> local tty out * 3 <-> remote tty in * 4 <-> remote tty out */ void consh(char c) { char buf[256]; int cpid, status, p; time_t start=0; putchar(c); if (prompt("Local command? ", buf)) return; kill(pid, SIGIOT); /* put TIPOUT into a wait state */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); ioctl(0, TIOCSETC, &defchars); read(repdes[0], (char *)&ccc, 1); /* * Set up file descriptors in the child and let it go... */ if ((cpid = fork()) < 0) printf("can't fork!\r\n"); else if (cpid) { start = time(0); while ((p = wait(&status)) > 0 && p != cpid); } else { register int i; dup2(FD, 3); dup2(3, 4); for (i = 5; i < 20; i++) close(i); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); execute(buf); printf("can't find `%s'\r\n", buf); exit(0); } if (boolean(value(VERBOSE))) prtime("away for ", time(0) - start); write(fildes[1], (char *)&ccc, 1); ioctl(0, TIOCSETC, &tchars); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); } #endif #ifdef TIPX /* * filexfer_help * * Display help for ~X * type = 0, general help, 1 = send help, 2 = receive help */ void filexfer_help(type) int type; { static char *ghelp[] = { "for send help, type ~Xs?; for receive help, type ~Xr?", "where ~ represents your escape character", (char *)0, }; static char *shelp[] = { "XMODEM (CHK, CRC) and XMODEM-1k/CRC", "sx [-ak] filename -a (ASCII) convert NL to CR/LF (default binary)", " -k use 1024 blocks instead of 128 (XMODEM-1k)", "YMODEM/CRC Batch", "sb/sy [-af] flist -a (ASCII) convert NL to CR/LF (default binary)", " -f transfer using full pathanme (default simple)", "ZMODEM (CRC-16, CRC-32)", "sz [-af+nNyrwo] [-w #] [-L #] [-l #] filelist", " -a (ASCII) convert NL to CR/LF (default binary)", " not all ZMODEM -f transfer using full pathname (default simple)", " receivers accept -+ Append to existing destination file", " all overwrite -n overwrite file if source newer", " or append -N overwrite file if source newer or longer", " options -y yes, absolutely overwrite existing file", " -r Resume/Recover interrupted file transfer", " -o use CRC-16 instead of CRC-32", " -z try to use rle compression", " -w # Window is # bytes (>= 256, multiple of 64)", " -L # Limit subpacket length to # bytes", " -l # Limit frame length to # bytes (l must >= L)", (char *)0 }; static char *rhelp[] = { "XMODEM (CHK, CRC) (rcvr tries CRC, then checksum)", " rx [-ab] filename", "YMODEM/CRC Batch rb/ry [-abu]", "ZMODEM (CRC-16, CRC-32) rz [-abu]", "Switches: -a force ASCII translation on receive", " -b force binary transfer", " -u convert uppercase filenames to lower case", (char *)0 }; char **hh; switch (type) { case 0: hh = ghelp; break; case 1: hh = shelp; break; case 2: hh = rhelp; break; default: printf("Wrong option in switch statement: type = %d.\n",type); exit(-1); break; } while (*hh) { fputs(*hh++, stdout); fputs("\r\n", stdout); } } #endif /* TIPX */ #ifdef TIPX /* * filexfer * * Fork a file transfer with: * 0 <-> local tty in * 1 <-> local tty out * 2 <-> local tty out * FD <-> remote tty in/out */ void filexfer(char c) { char buf[256]; char xcmd[256 + 24]; int cpid, status, p; time_t start=0; putchar(c); if (prompt("\r\nfile transfer command? (? for help) ", buf)) return; if (!strncmp(buf, "sz ", 3)) #ifdef HAYES sprintf(xcmd, "tipsz -Z -. %d -: %d ", FD, Cbaudrate); #else sprintf(xcmd, "tipsz -Z -. %d ", FD); #endif else if ((!strncmp(buf, "sb ", 3)) || (!strncmp(buf, "sy ", 3))) #ifdef HAYES sprintf(xcmd, "tipsz -Y -k -. %d -: %d ", FD, Cbaudrate); #else sprintf(xcmd, "tipsz -Y -k -. %d ", FD); #endif else if (!strncmp(buf, "sx ", 3)) #ifdef HAYES sprintf(xcmd, "tipsz -X -. %d -: %d ", FD, Cbaudrate); #else sprintf(xcmd, "tipsz -X -. %d ", FD); #endif else if (!strncmp(buf, "rz", 2)) #ifdef HAYES sprintf(xcmd, "tiprz -Z -. %d -: %d ", FD, Cbaudrate); #else sprintf(xcmd, "tiprz -Z -. %d ", FD); #endif else if ((!strncmp(buf, "ry", 2)) || (!strncmp(buf, "rb", 2))) #ifdef HAYES sprintf(xcmd, "tiprz -Y -. %d -: %d ", FD, Cbaudrate); #else sprintf(xcmd, "tiprz -Y -. %d ", FD); #endif else if (!strncmp(buf, "rx ", 3)) #ifdef HAYES sprintf(xcmd, "tiprz -X -. %d -: %d ", FD, Cbaudrate); #else sprintf(xcmd, "tiprz -X -. %d ", FD); #endif else if (!strncmp(buf, "?", 1)) { filexfer_help(0); return; } else if (!strncmp(buf, "s?", 2)) { filexfer_help(1); return; } else if (!strncmp(buf, "r?", 2)) { filexfer_help(2); return; } else { printf("unrecognized transfer command %s\r\n", buf); printf("(use sz, rz, etc.)\r\n"); return; } strcat(xcmd, buf + 3); kill(pid, SIGIOT); /* put TIPOUT into a wait state */ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); unraw(); read(repdes[0], (char *)&ccc, 1); if ((cpid = vfork()) < 0) printf("can't fork!\r\n"); else if (cpid) { start = time(0); while ((p = wait(&status)) > 0 && p != cpid); } else { register int i; for (i = 3; i < 20; i++) { if (i != FD) close(i); } signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); user_uid(); execl("/bin/sh", "sh", "-c", xcmd, (char *)0); printf("can't execute `%s'\n", xcmd); perror("execl"); exit(0); } prtime("away for ", time(0) - start); write(fildes[1], (char *)&ccc, 1); raw(); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); } #endif /* * Escape to local shell */ void shell(void) { int shpid, status; char *cp; printf("[sh]\r\n"); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); unraw(); if (shpid = fork()) { while (shpid != wait(&status)); raw(); printf("\r\n!\r\n"); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); return; } else { signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); if ((cp = rindex(value(SHELL), '/')) == NULL) cp = value(SHELL); else cp++; shell_uid(); execl(value(SHELL), cp, 0); printf("\r\ncan't execl!\r\n"); exit(1); } } /* * TIPIN portion of scripting * initiate the conversation with TIPOUT */ void setscript(void) { char c; /* * enable TIPOUT side for dialogue */ kill(pid, SIGEMT); if (boolean(value(SCRIPT))) write(fildes[1], value(RECORD), size(value(RECORD))); write(fildes[1], "\n", 1); /* * wait for TIPOUT to finish */ read(repdes[0], &c, 1); if (c == 'n') printf("can't create %s\r\n", value(RECORD)); } /* * Change current working directory of * local portion of tip */ void chdirectory(void) { char dirname[80]; register char *cp = dirname; if (prompt("[cd] ", dirname)) { if (stoprompt) return; cp = value(HOME); } if (chdir(cp) < 0) printf("%s: bad directory\r\n", cp); printf("!\r\n"); } #ifndef NeXT abort(msg) #else void tip_abort(msg) #endif /* NeXT */ char *msg; { kill(pid, SIGTERM); disconnect(msg); if (msg != NOSTR) printf("\r\n%s", msg); printf("\r\n[EOT]\r\n"); daemon_uid(); (void)uu_unlock(uucplock); unraw(); exit(0); } void finish(void) { char *dismsg; if ((dismsg = value(DISCONNECT)) != NOSTR) { write(FD, dismsg, strlen(dismsg)); sleep(5); } #ifndef NeXT abort(NOSTR); #else (void)tip_abort(NOSTR); #endif /* NeXT */ } void intcopy() { raw(); quit = 1; longjmp(intbuf, 1); } void execute(s) char *s; { register char *cp; if ((cp = rindex(value(SHELL), '/')) == NULL) cp = value(SHELL); else cp++; shell_uid(); execl(value(SHELL), cp, "-c", s, 0); } int args(buf, a) char *buf, *a[]; { register char *p = buf, *start; register char **parg = a; register int n = 0; do { while (*p && (*p == ' ' || *p == '\t')) p++; start = p; if (*p) *parg = p; while (*p && (*p != ' ' && *p != '\t')) p++; if (p != start) parg++, n++; if (*p) *p++ = '\0'; } while (*p); return (n); } void prtime(s, a) char *s; time_t a; { register i; int nums[3]; for (i = 0; i < 3; i++) { nums[i] = (int)(a % quant[i]); a /= quant[i]; } printf("%s", s); while (--i >= 0) if (nums[i] || (i == 0) && (nums[1] == 0) && (nums[2] == 0)) printf("%d %s%c ", nums[i], sep[i], nums[i] == 1 ? '\0' : 's'); printf("\r\n!\r\n"); } void variable(void) { char buf[256]; if (prompt("[set] ", buf)) return; vlex(buf); if (vtable[BEAUTIFY].v_access & CHANGED) { vtable[BEAUTIFY].v_access &= ~CHANGED; kill(pid, SIGSYS); } if (vtable[SCRIPT].v_access & CHANGED) { vtable[SCRIPT].v_access &= ~CHANGED; setscript(); /* * So that "set record=blah script" doesn't cause two transactions to * occur. */ if (vtable[RECORD].v_access & CHANGED) vtable[RECORD].v_access &= ~CHANGED; } if (vtable[RECORD].v_access & CHANGED) { vtable[RECORD].v_access &= ~CHANGED; if (boolean(value(SCRIPT))) setscript(); } if (vtable[TAND].v_access & CHANGED) { vtable[TAND].v_access &= ~CHANGED; if (boolean(value(TAND))) tandem("on"); else tandem("off"); } if (vtable[LECHO].v_access & CHANGED) { vtable[LECHO].v_access &= ~CHANGED; HD = boolean(value(LECHO)); } if (vtable[PARITY].v_access & CHANGED) { vtable[PARITY].v_access &= ~CHANGED; setparity(); } } /* * Turn tandem mode on or off for remote tty. */ void tandem(option) char *option; { struct sgttyb rmtty; ioctl(FD, TIOCGETP, &rmtty); if (strcmp(option, "on") == 0) { rmtty.sg_flags |= TANDEM; arg.sg_flags |= TANDEM; } else { rmtty.sg_flags &= ~TANDEM; arg.sg_flags &= ~TANDEM; } ioctl(FD, TIOCSETP, &rmtty); ioctl(0, TIOCSETP, &arg); } /* * Send a break. */ void genbrk(void) { ioctl(FD, TIOCSBRK, NULL); sleep(1); ioctl(FD, TIOCCBRK, NULL); } /* * Send a ^S. */ #ifdef TIPX void genctls(void) { static char ctls = 0x13; printf("^S"); write(FD, &ctls, 1); } #endif /* * Send a ^Q. */ #ifdef TIPX void genctlq(void) { static char ctlq = 0x11; printf("^Q"); write(FD, &ctlq, 1); } #endif /* * control rawthru mode */ #ifdef TIPX void rawthru_control(gch) char gch; { extern int rawthru; gch &= 0177; write(2, &gch, 1); if (gch == 'R') { rawthru = 1; kill(pid, SIGUSR1); } else { rawthru = 0; kill(pid, SIGUSR2); } } #endif /* * Suspend tip */ void suspend(c) char c; { unraw(); kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); raw(); } /* * expand a file name if it includes shell meta characters */ char * expand(name) char name[]; { static char xname[BUFSIZ]; char cmdbuf[BUFSIZ]; register int pid, l; register char *cp, *Shell; int s, pivec[2]; if (!anyof(name, "~{[*?$`'\"\\")) return (name); /* sigint = signal(SIGINT, SIG_IGN); */ if (pipe(pivec) < 0) { perror("pipe"); /* signal(SIGINT, sigint) */ return (name); } sprintf(cmdbuf, "echo %s", name); if ((pid = vfork()) == 0) { Shell = value(SHELL); if (Shell == NOSTR) Shell = _PATH_BSHELL; close(pivec[0]); close(1); dup(pivec[1]); close(pivec[1]); close(2); shell_uid(); execl(Shell, Shell, "-c", cmdbuf, 0); _exit(1); } if (pid == -1) { perror("fork"); close(pivec[0]); close(pivec[1]); return (NOSTR); } close(pivec[1]); l = read(pivec[0], xname, BUFSIZ); close(pivec[0]); while (wait(&s) != pid); ; s &= 0377; if (s != 0 && s != SIGPIPE) { fprintf(stderr, "\"Echo\" failed\n"); return (NOSTR); } if (l < 0) { perror("read"); return (NOSTR); } if (l == 0) { fprintf(stderr, "\"%s\": No match\n", name); return (NOSTR); } if (l == BUFSIZ) { fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); return (NOSTR); } xname[l] = 0; for (cp = &xname[l - 1]; *cp == '\n' && cp > xname; cp--); *++cp = '\0'; return (xname); } /* * Are any of the characters in the two strings the same? */ int anyof(s1, s2) register char *s1, *s2; { register int c; while (c = *s1++) if (any(c, s2)) return (1); return (0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.