📄 doio.c
字号:
if (statstab) stio = stab_io(statstab); else { str = statname; goto really_filename; } } else { statstab = arg[1].arg_ptr.arg_stab; str_set(statname,""); stio = stab_io(statstab); } if (stio && stio->ifp) {#if defined(STDSTDIO) || defined(atarist) /* this will work with atariST */ fstat(fileno(stio->ifp),&statcache); if (S_ISDIR(statcache.st_mode)) /* handle NFS glitch */ return arg->arg_type == O_FTTEXT ? &str_no : &str_yes; if (stio->ifp->_cnt <= 0) { i = getc(stio->ifp); if (i != EOF) (void)ungetc(i,stio->ifp); } if (stio->ifp->_cnt <= 0) /* null file is anything */ return &str_yes; len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base); s = stio->ifp->_base;#else fatal("-T and -B not implemented on filehandles");#endif } else { if (dowarn) warn("Test on unopened file <%s>", stab_ename(arg[1].arg_ptr.arg_stab)); errno = EBADF; return &str_undef; } } else { statstab = Nullstab; str_set(statname,str_get(str)); really_filename: i = open(str_get(str),0); if (i < 0) { if (dowarn && index(str_get(str), '\n')) warn(warn_nl, "open"); return &str_undef; } fstat(i,&statcache); len = read(i,tbuf,512); (void)close(i); if (len <= 0) { if (S_ISDIR(statcache.st_mode) && arg->arg_type == O_FTTEXT) return &str_no; /* special case NFS directories */ return &str_yes; /* null file is anything */ } s = tbuf; } /* now scan s to look for textiness */ for (i = 0; i < len; i++,s++) { if (!*s) { /* null never allowed in text */ odd += len; break; } else if (*s & 128) odd++; else if (*s < 32 && *s != '\n' && *s != '\r' && *s != '\b' && *s != '\t' && *s != '\f' && *s != 27) odd++; } if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */ return &str_no; else return &str_yes;}static char **Argv = Null(char **);static char *Cmd = Nullch;booldo_aexec(really,arglast)STR *really;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register int items = arglast[2] - sp; register char **a; char *tmps; if (items) { New(401,Argv, items+1, char*); a = Argv; for (st += ++sp; items > 0; items--,st++) { if (*st) *a++ = str_get(*st); else *a++ = ""; } *a = Nullch;#ifdef TAINT if (*Argv[0] != '/') /* will execvp use PATH? */ taintenv(); /* testing IFS here is overkill, probably */#endif if (really && *(tmps = str_get(really))) execvp(tmps,Argv); else execvp(Argv[0],Argv); } do_execfree(); return FALSE;}voiddo_execfree(){ if (Argv) { Safefree(Argv); Argv = Null(char **); } if (Cmd) { Safefree(Cmd); Cmd = Nullch; }}booldo_exec(cmd)char *cmd;{ register char **a; register char *s; char flags[10]; /* save an extra exec if possible */#ifdef CSH if (strnEQ(cmd,cshname,cshlen) && strnEQ(cmd+cshlen," -c",3)) { strcpy(flags,"-c"); s = cmd+cshlen+3; if (*s == 'f') { s++; strcat(flags,"f"); } if (*s == ' ') s++; if (*s++ == '\'') { char *ncmd = s; while (*s) s++; if (s[-1] == '\n') *--s = '\0'; if (s[-1] == '\'') { *--s = '\0'; execl(cshname,"csh", flags,ncmd,(char*)0); *s = '\''; return FALSE; } } }#endif /* CSH */ /* see if there are shell metacharacters in it */ /*SUPPRESS 530*/ for (s = cmd; *s && isALPHA(*s); s++) ; /* catch VAR=val gizmo */ if (*s == '=') goto doshell; for (s = cmd; *s; s++) { if (*s != ' ' && !isALPHA(*s) && index("$&*(){}[]'\";\\|?<>~`\n",*s)) { if (*s == '\n' && !s[1]) { *s = '\0'; break; } doshell: execl("/bin/sh","sh","-c",cmd,(char*)0); return FALSE; } } New(402,Argv, (s - cmd) / 2 + 2, char*); Cmd = nsavestr(cmd, s-cmd); a = Argv; for (s = Cmd; *s;) { while (*s && isSPACE(*s)) s++; if (*s) *(a++) = s; while (*s && !isSPACE(*s)) s++; if (*s) *s++ = '\0'; } *a = Nullch; if (Argv[0]) { execvp(Argv[0],Argv); if (errno == ENOEXEC) { /* for system V NIH syndrome */ do_execfree(); goto doshell; } } do_execfree(); return FALSE;}#ifdef HAS_SOCKETintdo_socket(stab, arglast)STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; int domain, type, protocol, fd; if (!stab) { errno = EBADF; return FALSE; } stio = stab_io(stab); if (!stio) stio = stab_io(stab) = stio_new(); else if (stio->ifp) do_close(stab,FALSE); domain = (int)str_gnum(st[++sp]); type = (int)str_gnum(st[++sp]); protocol = (int)str_gnum(st[++sp]);#ifdef TAINT taintproper("Insecure dependency in socket");#endif fd = socket(domain,type,protocol); if (fd < 0) return FALSE; stio->ifp = fdopen(fd, "r"); /* stdio gets confused about sockets */ stio->ofp = fdopen(fd, "w"); stio->type = 's'; if (!stio->ifp || !stio->ofp) { if (stio->ifp) fclose(stio->ifp); if (stio->ofp) fclose(stio->ofp); if (!stio->ifp && !stio->ofp) close(fd); return FALSE; } return TRUE;}intdo_bind(stab, arglast)STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; char *addr; if (!stab) goto nuts; stio = stab_io(stab); if (!stio || !stio->ifp) goto nuts; addr = str_get(st[++sp]);#ifdef TAINT taintproper("Insecure dependency in bind");#endif return bind(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;nuts: if (dowarn) warn("bind() on closed fd"); errno = EBADF; return FALSE;}intdo_connect(stab, arglast)STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; char *addr; if (!stab) goto nuts; stio = stab_io(stab); if (!stio || !stio->ifp) goto nuts; addr = str_get(st[++sp]);#ifdef TAINT taintproper("Insecure dependency in connect");#endif return connect(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;nuts: if (dowarn) warn("connect() on closed fd"); errno = EBADF; return FALSE;}intdo_listen(stab, arglast)STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; int backlog; if (!stab) goto nuts; stio = stab_io(stab); if (!stio || !stio->ifp) goto nuts; backlog = (int)str_gnum(st[++sp]); return listen(fileno(stio->ifp), backlog) >= 0;nuts: if (dowarn) warn("listen() on closed fd"); errno = EBADF; return FALSE;}voiddo_accept(str, nstab, gstab)STR *str;STAB *nstab;STAB *gstab;{ register STIO *nstio; register STIO *gstio; int len = sizeof buf; int fd; if (!nstab) goto badexit; if (!gstab) goto nuts; gstio = stab_io(gstab); nstio = stab_io(nstab); if (!gstio || !gstio->ifp) goto nuts; if (!nstio) nstio = stab_io(nstab) = stio_new(); else if (nstio->ifp) do_close(nstab,FALSE); fd = accept(fileno(gstio->ifp),(struct sockaddr *)buf,&len); if (fd < 0) goto badexit; nstio->ifp = fdopen(fd, "r"); nstio->ofp = fdopen(fd, "w"); nstio->type = 's'; if (!nstio->ifp || !nstio->ofp) { if (nstio->ifp) fclose(nstio->ifp); if (nstio->ofp) fclose(nstio->ofp); if (!nstio->ifp && !nstio->ofp) close(fd); goto badexit; } str_nset(str, buf, len); return;nuts: if (dowarn) warn("accept() on closed fd"); errno = EBADF;badexit: str_sset(str,&str_undef); return;}intdo_shutdown(stab, arglast)STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; int how; if (!stab) goto nuts; stio = stab_io(stab); if (!stio || !stio->ifp) goto nuts; how = (int)str_gnum(st[++sp]); return shutdown(fileno(stio->ifp), how) >= 0;nuts: if (dowarn) warn("shutdown() on closed fd"); errno = EBADF; return FALSE;}intdo_sopt(optype, stab, arglast)int optype;STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; int fd; unsigned int lvl; unsigned int optname; if (!stab) goto nuts; stio = stab_io(stab); if (!stio || !stio->ifp) goto nuts; fd = fileno(stio->ifp); lvl = (unsigned int)str_gnum(st[sp+1]); optname = (unsigned int)str_gnum(st[sp+2]); switch (optype) { case O_GSOCKOPT: st[sp] = str_2mortal(Str_new(22,257)); st[sp]->str_cur = 256; st[sp]->str_pok = 1; if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, (int*)&st[sp]->str_cur) < 0) goto nuts; break; case O_SSOCKOPT: st[sp] = st[sp+3]; if (setsockopt(fd, lvl, optname, st[sp]->str_ptr, st[sp]->str_cur) < 0) goto nuts; st[sp] = &str_yes; break; } return sp;nuts: if (dowarn) warn("[gs]etsockopt() on closed fd"); st[sp] = &str_undef; errno = EBADF; return sp;}intdo_getsockname(optype, stab, arglast)int optype;STAB *stab;int *arglast;{ register STR **st = stack->ary_array; register int sp = arglast[1]; register STIO *stio; int fd; if (!stab) goto nuts; stio = stab_io(stab); if (!stio || !stio->ifp) goto nuts; st[sp] = str_2mortal(Str_new(22,257)); st[sp]->str_cur = 256; st[sp]->str_pok = 1; fd = fileno(stio->ifp); switch (optype) { case O_GETSOCKNAME: if (getsockname(fd, st[sp]->str_ptr, (int*)&st[sp]->str_cur) < 0) goto nuts2; break; case O_GETPEERNAME: if (getpeername(fd, st[sp]->str_ptr, (int*)&st[sp]->str_cur) < 0) goto nuts2; break; } return sp;nuts: if (dowarn) warn("get{sock,peer}name() on closed fd"); errno = EBADF;nuts2: st[sp] = &str_undef; return sp;}intdo_ghent(which,gimme,arglast)int which;int gimme;int *arglast;{ register ARRAY *ary = stack; register int sp = arglast[0]; register char **elem; register STR *str; struct hostent *gethostbyname(); struct hostent *gethostbyaddr();#ifdef HAS_GETHOSTENT struct hostent *gethostent();#endif struct hostent *hent; unsigned long len; if (which == O_GHBYNAME) { char *name = str_get(ary->ary_array[sp+1]); hent = gethostbyname(name); } else if (which == O_GHBYADDR) { STR *addrstr = ary->ary_array[sp+1]; int addrtype = (int)str_gnum(ary->ary_array[sp+2]); char *addr = str_get(addrstr); hent = gethostbyaddr(addr,addrstr->str_cur,addrtype); } else#ifdef HAS_GETHOSTENT hent = gethostent();#else fatal("gethostent not implemented");#endif#ifdef HOST_NOT_FOUND if (!hent) statusvalue = (unsigned short)h_errno & 0xffff;#endif if (gimme != G_ARRAY) { astore(ary, ++sp, str = str_mortal(&str_undef)); if (hent) { if (which == O_GHBYNAME) {#ifdef h_addr str_nset(str, *hent->h_addr, hent->h_length);#else str_nset(str, hent->h_addr, hent->h_length);#endif } else str_set(str, hent->h_name); } return sp; } if (hent) {#ifndef lint (void)astore(ary, ++sp, str = str_mortal(&str_no)); str_set(str, hent->h_name); (void)astore(ary, ++sp, str = str_mortal(&str_no)); for (elem = hent->h_aliases; *elem; elem++) { str_cat(str, *elem); if (elem[1]) str_ncat(str," ",1); } (void)astore(ary, ++sp, str = str_mortal(&str_no)); str_numset(str, (double)hent->h_addrtype); (void)astore(ary, ++sp, str = str_mortal(&str_no)); len = hent->h_length; str_numset(str, (double)len);#ifdef h_addr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -