|
|
1.1 ! root 1: #include "sam.h" ! 2: #include "parse.h" ! 3: #ifdef SUN ! 4: /* a hack to get around redef of ushort in sys/types.h . ! 5: this depends on non-use of ushort in this file */ ! 6: #define ushort USHORT ! 7: #endif ! 8: #include <sys/types.h> ! 9: #include <sys/stat.h> ! 10: #include <signal.h> ! 11: #include <setjmp.h> ! 12: ! 13: extern jmp_buf mainloop; ! 14: ! 15: uchar errfile[64]; ! 16: String unixcmd; /* null terminated */ ! 17: ! 18: Unix(f, type, s, nest) ! 19: register File *f; ! 20: register type; ! 21: register String *s; ! 22: { ! 23: register pid, rpid; ! 24: int (*onbpipe)(); ! 25: int retcode; ! 26: int pipe1[2], pipe2[2]; ! 27: if(s->s[0]==0 && unixcmd.s[0]==0) ! 28: error(Enocmd); ! 29: else if(s->s[0]) ! 30: strdupstr(&unixcmd, s); ! 31: if(downloaded){ ! 32: strcpy(errfile, (uchar *)home); ! 33: strcat((char *)errfile, "/sam.err"); ! 34: }else ! 35: strcpy(errfile, (uchar *)"/dev/tty"); ! 36: if(type!='!' && pipe(pipe1)==-1) ! 37: error(Epipe); ! 38: unlink((char *)errfile); ! 39: if((pid=fork()) == 0){ ! 40: if(downloaded){ /* also put nasty fd's into errfile */ ! 41: int fd=creat((char *)errfile, 0666); ! 42: if(fd<0) ! 43: fd=creat("/dev/null", 0666); ! 44: #ifdef V8 ! 45: close(3); /* v8 /dev/tty */ ! 46: open("/dev/null", 2); ! 47: #endif ! 48: close(2); ! 49: dup(fd); ! 50: close(fd); ! 51: /* 2 now points at err file */ ! 52: close(1); ! 53: if(type == '>') ! 54: dup(2); ! 55: else if(type=='!'){ ! 56: dup(2); ! 57: fd=open("/dev/null", 0); ! 58: close(0); ! 59: dup(fd); ! 60: close(fd); ! 61: } ! 62: } ! 63: if(type!='!') { ! 64: if(type=='<' || type=='|'){ ! 65: close(1); ! 66: dup(pipe1[1]); ! 67: }else if(type == '>'){ ! 68: close(0); ! 69: dup(pipe1[0]); ! 70: } ! 71: close(pipe1[0]); ! 72: close(pipe1[1]); ! 73: } ! 74: if(type=='|'){ ! 75: if(pipe(pipe2)==-1) ! 76: exit(1); ! 77: if((pid=fork())==0){ ! 78: /* ! 79: * It's ok if we get SIGPIPE here ! 80: */ ! 81: close(pipe2[0]); ! 82: io=pipe2[1]; ! 83: if(retcode=!setjmp(mainloop)) /* assignment = */ ! 84: (void)writeio(f); ! 85: exit(retcode); ! 86: } ! 87: if(pid==-1){ ! 88: fprint(2, "Can't fork?!\n"); ! 89: exit(1); ! 90: } ! 91: close(0); ! 92: dup(pipe2[0]); ! 93: close(pipe2[0]); ! 94: close(pipe2[1]); ! 95: } ! 96: Dclosefd(); ! 97: if(type=='<'){ ! 98: close(0); /* so it won't read from terminal */ ! 99: open("/dev/null", 0); ! 100: } ! 101: execlp("sh", "sh", "-c", unixcmd.s, (char *)0); ! 102: exit(-1); ! 103: } ! 104: if(pid==-1) ! 105: error(Efork); ! 106: if(type=='<' || type=='|'){ ! 107: if(downloaded) ! 108: outTl(Hsnarflen, addr.r.p2-addr.r.p1); ! 109: snarf(f, addr.r.p1, addr.r.p2); ! 110: Fdelete(f, addr.r.p1, addr.r.p2); ! 111: close(pipe1[1]); ! 112: io=pipe1[0]; ! 113: f->dot.r.p2=addr.r.p2+readio(f, (int *)0, 0); ! 114: f->dot.r.p1=addr.r.p2; ! 115: closeio((Posn)-1); ! 116: }else if(type=='>'){ ! 117: onbpipe = signal(SIGPIPE, SIG_IGN); ! 118: close(pipe1[0]); ! 119: io=pipe1[1]; ! 120: (void)writeio(f); ! 121: closeio((Posn)-1); ! 122: signal(SIGPIPE, onbpipe); ! 123: } ! 124: do; while ((rpid = wait(&retcode)) != pid && rpid != -1); ! 125: retcode=(retcode>>8)&0377; ! 126: if(type=='|' || type=='<') ! 127: if(retcode!=0) ! 128: warn(Wbadstatus); ! 129: checkerrs(); ! 130: if(!nest) ! 131: dprint("!\n"); ! 132: } ! 133: checkerrs(){ ! 134: struct stat statb; ! 135: char buf[256]; ! 136: register f; ! 137: register n, nl; ! 138: register char *p; ! 139: if(stat((char *)errfile, &statb)==0 && statb.st_size){ ! 140: if((f=open((char *)errfile, 0)) != -1){ ! 141: if((n=read(f, buf, sizeof buf-1))>0){ ! 142: for(nl=0,p=buf; nl<3 && p<&buf[n]; p++) ! 143: if(*p=='\n') ! 144: nl++; ! 145: *p=0; ! 146: dprint("%s", buf); ! 147: if(p-buf < statb.st_size-1) ! 148: dprint("(sam: more in %s)\n", errfile); ! 149: } ! 150: close(f); ! 151: } ! 152: }else ! 153: unlink((char *)errfile); ! 154: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.