1 /* $Header: doio.c,v 3.0.1.8 90/03/27 15:44:02 lwall Locked $
3 * Copyright (c) 1989, Larry Wall
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
9 * Revision 3.0.1.8 90/03/27 15:44:02 lwall
10 * patch16: MSDOS support
11 * patch16: support for machines that can't cast negative floats to unsigned ints
12 * patch16: system() can lose arguments passed to shell scripts on SysV machines
14 * Revision 3.0.1.7 90/03/14 12:26:24 lwall
15 * patch15: commands involving execs could cause malloc arena corruption
17 * Revision 3.0.1.6 90/03/12 16:30:07 lwall
18 * patch13: system 'FOO=bar command' didn't invoke sh as it should
20 * Revision 3.0.1.5 90/02/28 17:01:36 lwall
21 * patch9: open(FOO,"$filename\0") will now protect trailing spaces in filename
22 * patch9: removed obsolete checks to avoid opening block devices
23 * patch9: removed references to acusec and modusec that some utime.h's have
24 * patch9: added pipe function
26 * Revision 3.0.1.4 89/12/21 19:55:10 lwall
27 * patch7: select now works on big-endian machines
28 * patch7: errno may now be a macro with an lvalue
29 * patch7: ANSI strerror() is now supported
30 * patch7: Configure now detects DG/UX thingies like [sg]etpgrp2 and utime.h
32 * Revision 3.0.1.3 89/11/17 15:13:06 lwall
33 * patch5: some systems have symlink() but not lstat()
34 * patch5: some systems have dirent.h but not readdir()
36 * Revision 3.0.1.2 89/11/11 04:25:51 lwall
37 * patch2: orthogonalized the file modes some so we can have <& +<& etc.
38 * patch2: do_open() now detects sockets passed to process from parent
39 * patch2: fd's above 2 are now closed on exec
40 * patch2: csh code can now use csh from other than /bin
41 * patch2: getsockopt, get{sock,peer}name didn't define result properly
42 * patch2: warn("shutdown") was replicated
43 * patch2: gethostbyname was misdeclared
44 * patch2: telldir() is sometimes a macro
46 * Revision 3.0.1.1 89/10/26 23:10:05 lwall
47 * patch1: Configure now checks for BSD shadow passwords
49 * Revision 3.0 89/10/18 15:10:54 lwall
58 #include <sys/socket.h>
73 do_open(stab,name,len)
79 register STIO *stio = stab_io(stab);
80 char *myname = savestr(name);
84 char mode[3]; /* stdio file mode ("r\0" or "r+\0") */
87 forkprocess = 1; /* assume true if no fork */
88 while (len && isspace(name[len-1]))
91 stio = stab_io(stab) = stio_new();
93 fd = fileno(stio->ifp);
94 if (stio->type == '|')
95 result = mypclose(stio->ifp);
96 else if (stio->ifp != stio->ofp) {
99 result = fclose(stio->ifp);
101 else if (stio->type != '-')
102 result = fclose(stio->ifp);
105 if (result == EOF && fd > 2)
106 fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
108 stio->ofp = stio->ifp = Nullfp;
110 if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
121 for (name++; isspace(*name); name++) ;
124 taintproper("Insecure dependency in piped open");
126 fp = mypopen(name,"w");
129 else if (*name == '>') {
131 taintproper("Insecure dependency in open");
135 mode[0] = stio->type = 'a';
144 while (isspace(*name))
149 stab = stabent(name,FALSE);
150 if (!stab || !stab_io(stab))
152 if (stab_io(stab) && stab_io(stab)->ifp) {
153 fd = fileno(stab_io(stab)->ifp);
154 if (stab_io(stab)->type == 's')
160 fp = fdopen(dup(fd),mode);
163 while (isspace(*name))
165 if (strEQ(name,"-")) {
170 fp = fopen(name,mode);
178 while (isspace(*name))
182 if (strEQ(name,"-")) {
187 fp = fopen(name,mode);
189 else if (name[len-1] == '|') {
192 taintproper("Insecure dependency in piped open");
195 while (len && isspace(name[len-1]))
197 for (; isspace(*name); name++) ;
198 fp = mypopen(name,"r");
203 for (; isspace(*name); name++) ;
204 if (strEQ(name,"-")) {
209 fp = fopen(name,"r");
216 stio->type != '|' && stio->type != '-') {
217 if (fstat(fileno(fp),&statbuf) < 0) {
221 result = (statbuf.st_mode & S_IFMT);
223 if (result == S_IFSOCK || result == 0)
224 stio->type = 's'; /* in case a socket was passed in to us */
227 #if defined(FCNTL) && defined(F_SETFD)
234 if (stio->type != 's')
237 stio->ofp = fdopen(fileno(fp),"w");
248 int filemode,fileuid,filegid;
250 while (alen(stab_xarray(stab)) >= 0) {
251 str = ashift(stab_xarray(stab));
252 str_sset(stab_val(stab),str);
253 STABSET(stab_val(stab));
254 oldname = str_get(stab_val(stab));
255 if (do_open(stab,oldname,stab_val(stab)->str_cur)) {
258 taintproper("Insecure dependency in inplace open");
260 filemode = statbuf.st_mode;
261 fileuid = statbuf.st_uid;
262 filegid = statbuf.st_gid;
264 str_cat(str,inplace);
266 (void)rename(oldname,str->str_ptr);
268 (void)UNLINK(str->str_ptr);
269 (void)link(oldname,str->str_ptr);
270 (void)UNLINK(oldname);
274 (void)UNLINK(oldname);
278 str_cat(str,oldname);
279 errno = 0; /* in case sprintf set errno */
280 if (!do_open(argvoutstab,str->str_ptr,str->str_cur))
281 fatal("Can't do inplace edit");
282 defoutstab = argvoutstab;
284 (void)fchmod(fileno(stab_io(argvoutstab)->ifp),filemode);
286 (void)chmod(oldname,filemode);
289 (void)fchown(fileno(stab_io(argvoutstab)->ifp),fileuid,filegid);
292 (void)chown(oldname,fileuid,filegid);
297 return stab_io(stab)->ifp;
300 fprintf(stderr,"Can't open %s\n",str_get(str));
304 (void)do_close(argvoutstab,FALSE);
305 defoutstab = stabent("STDOUT",TRUE);
312 do_pipe(str, rstab, wstab)
317 register STIO *rstio;
318 register STIO *wstio;
326 rstio = stab_io(rstab);
327 wstio = stab_io(wstab);
330 rstio = stab_io(rstab) = stio_new();
332 do_close(rstab,FALSE);
334 wstio = stab_io(wstab) = stio_new();
336 do_close(wstab,FALSE);
340 rstio->ifp = fdopen(fd[0], "r");
341 wstio->ofp = fdopen(fd[1], "w");
342 wstio->ifp = wstio->ofp;
346 str_sset(str,&str_yes);
350 str_sset(str,&str_undef);
356 do_close(stab,explicit)
361 register STIO *stio = stab_io(stab);
364 if (!stio) { /* never opened */
365 if (dowarn && explicit)
366 warn("Close on unopened file <%s>",stab_name(stab));
370 if (stio->type == '|') {
371 status = mypclose(stio->ifp);
372 retval = (status >= 0);
373 statusvalue = (unsigned short)status & 0xffff;
375 else if (stio->type == '-')
378 if (stio->ofp && stio->ofp != stio->ifp) /* a socket */
380 retval = (fclose(stio->ifp) != EOF);
382 stio->ofp = stio->ifp = Nullfp;
397 if (!stab) { /* eof() */
399 stio = stab_io(argvstab);
404 stio = stab_io(stab);
411 #ifdef STDSTDIO /* (the code works without this) */
412 if (stio->ifp->_cnt > 0) /* cheat a little, since */
413 return FALSE; /* this is the most usual case */
416 ch = getc(stio->ifp);
418 (void)ungetc(ch, stio->ifp);
421 if (!stab) { /* not necessarily a real EOF yet? */
422 if (!nextargv(argvstab)) /* get another fp handy */
426 return TRUE; /* normal fp, definitely end of file */
440 stio = stab_io(stab);
441 if (!stio || !stio->ifp)
445 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
447 return ftell(stio->ifp);
451 warn("tell() on unopened file");
456 do_seek(stab, pos, whence)
466 stio = stab_io(stab);
467 if (!stio || !stio->ifp)
471 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
473 return fseek(stio->ifp, pos, whence) >= 0;
477 warn("seek() on unopened file");
482 do_ctl(optype,stab,func,argstr)
492 if (!stab || !argstr)
494 stio = stab_io(stab);
498 if (argstr->str_pok || !argstr->str_nok) {
499 if (!argstr->str_pok)
504 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
508 retval = IOCPARM_LEN(func); /* on BSDish systes we're safe */
510 retval = 256; /* otherwise guess at what's safe */
512 if (argstr->str_cur < retval) {
513 str_grow(argstr,retval+1);
514 argstr->str_cur = retval;
518 s[argstr->str_cur] = 17; /* a little sanity check here */
521 retval = (int)str_gnum(argstr);
522 s = (char*)retval; /* ouch */
526 if (optype == O_IOCTL)
527 retval = ioctl(fileno(stio->ifp), func, s);
530 retval = fcntl(fileno(stio->ifp), func, s);
532 fatal("fcntl is not implemented");
538 if (argstr->str_pok) {
539 if (s[argstr->str_cur] != 17)
540 fatal("Return value overflowed string");
541 s[argstr->str_cur] = 0; /* put our null back */
547 do_stat(str,arg,gimme,arglast)
553 register ARRAY *ary = stack;
554 register int sp = arglast[0] + 1;
558 if ((arg[1].arg_type & A_MASK) == A_WORD) {
559 tmpstab = arg[1].arg_ptr.arg_stab;
560 if (tmpstab != defstab) {
562 str_set(statname,"");
563 if (!stab_io(tmpstab) ||
564 fstat(fileno(stab_io(tmpstab)->ifp),&statcache) < 0) {
570 str_sset(statname,ary->ary_array[sp]);
573 if (arg->arg_type == O_LSTAT)
574 i = lstat(str_get(statname),&statcache);
577 i = stat(str_get(statname),&statcache);
582 if (gimme != G_ARRAY) {
584 str_sset(str,&str_yes);
586 str_sset(str,&str_undef);
588 ary->ary_array[sp] = str;
594 (void)astore(ary,++sp,
595 str_2static(str_nmake((double)statcache.st_dev)));
596 (void)astore(ary,++sp,
597 str_2static(str_nmake((double)statcache.st_ino)));
598 (void)astore(ary,++sp,
599 str_2static(str_nmake((double)statcache.st_mode)));
600 (void)astore(ary,++sp,
601 str_2static(str_nmake((double)statcache.st_nlink)));
602 (void)astore(ary,++sp,
603 str_2static(str_nmake((double)statcache.st_uid)));
604 (void)astore(ary,++sp,
605 str_2static(str_nmake((double)statcache.st_gid)));
606 (void)astore(ary,++sp,
607 str_2static(str_nmake((double)statcache.st_rdev)));
608 (void)astore(ary,++sp,
609 str_2static(str_nmake((double)statcache.st_size)));
610 (void)astore(ary,++sp,
611 str_2static(str_nmake((double)statcache.st_atime)));
612 (void)astore(ary,++sp,
613 str_2static(str_nmake((double)statcache.st_mtime)));
614 (void)astore(ary,++sp,
615 str_2static(str_nmake((double)statcache.st_ctime)));
617 (void)astore(ary,++sp,
618 str_2static(str_nmake((double)statcache.st_blksize)));
619 (void)astore(ary,++sp,
620 str_2static(str_nmake((double)statcache.st_blocks)));
622 (void)astore(ary,++sp,
623 str_2static(str_make("",0)));
624 (void)astore(ary,++sp,
625 str_2static(str_make("",0)));
628 (void)astore(ary,++sp,str_nmake(0.0));
635 looks_like_number(str)
644 send = s + str->str_cur;
649 if (*s == '+' || *s == '-')
657 else if (s == str->str_ptr)
663 if (*s == 'e' || *s == 'E') {
665 if (*s == '+' || *s == '-')
686 warn("print to unopened file");
692 ((str->str_nok && str->str_u.str_nval != 0.0)
693 || (looks_like_number(str) && str_gnum(str) != 0.0) ) )
694 fprintf(fp, ofmt, str->str_u.str_nval);
697 if (*tmps == 'S' && tmps[1] == 't' && tmps[2] == 'a' && tmps[3] == 'b'
698 && str->str_cur == sizeof(STBP) && strlen(tmps) < str->str_cur) {
699 tmps = stab_name(((STAB*)str)); /* a stab value, be nice */
700 str = ((STAB*)str)->str_magic;
703 if (str->str_cur && fwrite(tmps,1,str->str_cur,fp) == 0)
710 do_aprint(arg,fp,arglast)
715 register STR **st = stack->ary_array;
716 register int sp = arglast[1];
718 register int items = arglast[2] - sp;
722 warn("print to unopened file");
726 if (arg->arg_type == O_PRTF) {
727 do_sprintf(arg->arg_ptr.arg_str,items,st);
728 retval = do_print(arg->arg_ptr.arg_str,fp);
731 retval = (items <= 0);
732 for (; items > 0; items--,st++) {
733 if (retval && ofslen) {
734 if (fwrite(ofs, 1, ofslen, fp) == 0) {
739 if (!(retval = do_print(*st, fp)))
742 if (retval && orslen)
743 if (fwrite(ors, 1, orslen, fp) == 0)
756 if (arg[1].arg_type & A_DONT) {
757 stio = stab_io(arg[1].arg_ptr.arg_stab);
758 if (stio && stio->ifp) {
759 statstab = arg[1].arg_ptr.arg_stab;
760 str_set(statname,"");
761 return fstat(fileno(stio->ifp), &statcache);
764 if (arg[1].arg_ptr.arg_stab == defstab)
767 warn("Stat on unopened file <%s>",
768 stab_name(arg[1].arg_ptr.arg_stab));
770 str_set(statname,"");
776 str_sset(statname,str);
777 return stat(str_get(str),&statcache);
793 if (arg[1].arg_type & A_DONT) {
794 if (arg[1].arg_ptr.arg_stab == defstab) {
796 stio = stab_io(statstab);
799 goto really_filename;
803 statstab = arg[1].arg_ptr.arg_stab;
804 str_set(statname,"");
805 stio = stab_io(statstab);
807 if (stio && stio->ifp) {
809 fstat(fileno(stio->ifp),&statcache);
810 if (stio->ifp->_cnt <= 0) {
813 (void)ungetc(i,stio->ifp);
815 if (stio->ifp->_cnt <= 0) /* null file is anything */
817 len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base);
818 s = stio->ifp->_base;
820 fatal("-T and -B not implemented on filehandles\n");
825 warn("Test on unopened file <%s>",
826 stab_name(arg[1].arg_ptr.arg_stab));
832 str_sset(statname,str);
834 i = open(str_get(str),0);
838 len = read(i,tbuf,512);
839 if (len <= 0) /* null file is anything */
845 /* now scan s to look for textiness */
847 for (i = 0; i < len; i++,s++) {
848 if (!*s) { /* null never allowed in text */
855 *s != '\n' && *s != '\r' && *s != '\b' &&
856 *s != '\t' && *s != '\f' && *s != 27)
860 if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */
867 do_aexec(really,arglast)
871 register STR **st = stack->ary_array;
872 register int sp = arglast[1];
873 register int items = arglast[2] - sp;
879 New(401,argv, items+1, char*);
881 for (st += ++sp; items > 0; items--,st++) {
889 if (*argv[0] != '/') /* will execvp use PATH? */
890 taintenv(); /* testing IFS here is overkill, probably */
892 if (really && *(tmps = str_get(really)))
895 execvp(argv[0],argv);
913 taintproper("Insecure dependency in exec");
916 /* save an extra exec if possible */
919 if (strnEQ(cmd,cshname,cshlen) && strnEQ(cmd+cshlen," -c",3)) {
937 execl(cshname,"csh", flags,ncmd,(char*)0);
945 /* see if there are shell metacharacters in it */
947 for (s = cmd; *s && isalpha(*s); s++) ; /* catch VAR=val gizmo */
950 for (s = cmd; *s; s++) {
951 if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`\n",*s)) {
952 if (*s == '\n' && !s[1]) {
957 execl("/bin/sh","sh","-c",cmd,(char*)0);
961 New(402,argv, (s - cmd) / 2 + 2, char*);
962 cmd2 = nsavestr(cmd, s-cmd);
964 for (s = cmd2; *s;) {
965 while (*s && isspace(*s)) s++;
968 while (*s && !isspace(*s)) s++;
974 execvp(argv[0],argv);
975 if (errno == ENOEXEC) { /* for system V NIH syndrome */
988 do_socket(stab, arglast)
992 register STR **st = stack->ary_array;
993 register int sp = arglast[1];
995 int domain, type, protocol, fd;
1000 stio = stab_io(stab);
1002 stio = stab_io(stab) = stio_new();
1004 do_close(stab,FALSE);
1006 domain = (int)str_gnum(st[++sp]);
1007 type = (int)str_gnum(st[++sp]);
1008 protocol = (int)str_gnum(st[++sp]);
1010 taintproper("Insecure dependency in socket");
1012 fd = socket(domain,type,protocol);
1015 stio->ifp = fdopen(fd, "r"); /* stdio gets confused about sockets */
1016 stio->ofp = fdopen(fd, "w");
1023 do_bind(stab, arglast)
1027 register STR **st = stack->ary_array;
1028 register int sp = arglast[1];
1029 register STIO *stio;
1035 stio = stab_io(stab);
1036 if (!stio || !stio->ifp)
1039 addr = str_get(st[++sp]);
1041 taintproper("Insecure dependency in bind");
1043 return bind(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
1047 warn("bind() on closed fd");
1053 do_connect(stab, arglast)
1057 register STR **st = stack->ary_array;
1058 register int sp = arglast[1];
1059 register STIO *stio;
1065 stio = stab_io(stab);
1066 if (!stio || !stio->ifp)
1069 addr = str_get(st[++sp]);
1071 taintproper("Insecure dependency in connect");
1073 return connect(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
1077 warn("connect() on closed fd");
1083 do_listen(stab, arglast)
1087 register STR **st = stack->ary_array;
1088 register int sp = arglast[1];
1089 register STIO *stio;
1095 stio = stab_io(stab);
1096 if (!stio || !stio->ifp)
1099 backlog = (int)str_gnum(st[++sp]);
1100 return listen(fileno(stio->ifp), backlog) >= 0;
1104 warn("listen() on closed fd");
1109 do_accept(str, nstab, gstab)
1114 register STIO *nstio;
1115 register STIO *gstio;
1116 int len = sizeof buf;
1124 gstio = stab_io(gstab);
1125 nstio = stab_io(nstab);
1127 if (!gstio || !gstio->ifp)
1130 nstio = stab_io(nstab) = stio_new();
1131 else if (nstio->ifp)
1132 do_close(nstab,FALSE);
1134 fd = accept(fileno(gstio->ifp),buf,&len);
1137 nstio->ifp = fdopen(fd, "r");
1138 nstio->ofp = fdopen(fd, "w");
1141 str_nset(str, buf, len);
1146 warn("accept() on closed fd");
1148 str_sset(str,&str_undef);
1153 do_shutdown(stab, arglast)
1157 register STR **st = stack->ary_array;
1158 register int sp = arglast[1];
1159 register STIO *stio;
1165 stio = stab_io(stab);
1166 if (!stio || !stio->ifp)
1169 how = (int)str_gnum(st[++sp]);
1170 return shutdown(fileno(stio->ifp), how) >= 0;
1174 warn("shutdown() on closed fd");
1180 do_sopt(optype, stab, arglast)
1185 register STR **st = stack->ary_array;
1186 register int sp = arglast[1];
1187 register STIO *stio;
1195 stio = stab_io(stab);
1196 if (!stio || !stio->ifp)
1199 fd = fileno(stio->ifp);
1200 lvl = (int)str_gnum(st[sp+1]);
1201 optname = (int)str_gnum(st[sp+2]);
1204 st[sp] = str_2static(str_new(257));
1205 st[sp]->str_cur = 256;
1206 st[sp]->str_pok = 1;
1207 if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1212 if (setsockopt(fd, lvl, optname, st[sp]->str_ptr, st[sp]->str_cur) < 0)
1222 warn("[gs]etsockopt() on closed fd");
1223 st[sp] = &str_undef;
1229 do_getsockname(optype, stab, arglast)
1234 register STR **st = stack->ary_array;
1235 register int sp = arglast[1];
1236 register STIO *stio;
1242 stio = stab_io(stab);
1243 if (!stio || !stio->ifp)
1246 st[sp] = str_2static(str_new(257));
1247 st[sp]->str_cur = 256;
1248 st[sp]->str_pok = 1;
1249 fd = fileno(stio->ifp);
1252 if (getsockname(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1256 if (getpeername(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1265 warn("get{sock,peer}name() on closed fd");
1266 st[sp] = &str_undef;
1272 do_ghent(which,gimme,arglast)
1277 register ARRAY *ary = stack;
1278 register int sp = arglast[0];
1279 register char **elem;
1281 struct hostent *gethostbyname();
1282 struct hostent *gethostbyaddr();
1284 struct hostent *gethostent();
1286 struct hostent *hent;
1289 if (gimme != G_ARRAY) {
1290 astore(ary, ++sp, str_static(&str_undef));
1294 if (which == O_GHBYNAME) {
1295 char *name = str_get(ary->ary_array[sp+1]);
1297 hent = gethostbyname(name);
1299 else if (which == O_GHBYADDR) {
1300 STR *addrstr = ary->ary_array[sp+1];
1301 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1302 char *addr = str_get(addrstr);
1304 hent = gethostbyaddr(addr,addrstr->str_cur,addrtype);
1308 hent = gethostent();
1310 fatal("gethostent not implemented");
1314 (void)astore(ary, ++sp, str = str_static(&str_no));
1315 str_set(str, hent->h_name);
1316 (void)astore(ary, ++sp, str = str_static(&str_no));
1317 for (elem = hent->h_aliases; *elem; elem++) {
1318 str_cat(str, *elem);
1320 str_ncat(str," ",1);
1322 (void)astore(ary, ++sp, str = str_static(&str_no));
1323 str_numset(str, (double)hent->h_addrtype);
1324 (void)astore(ary, ++sp, str = str_static(&str_no));
1325 len = hent->h_length;
1326 str_numset(str, (double)len);
1328 for (elem = hent->h_addr_list; *elem; elem++) {
1329 (void)astore(ary, ++sp, str = str_static(&str_no));
1330 str_nset(str, *elem, len);
1333 (void)astore(ary, ++sp, str = str_static(&str_no));
1334 str_nset(str, hent->h_addr, len);
1339 (void)astore(ary, ++sp, str_static(&str_no));
1347 do_gnent(which,gimme,arglast)
1352 register ARRAY *ary = stack;
1353 register int sp = arglast[0];
1354 register char **elem;
1356 struct netent *getnetbyname();
1357 struct netent *getnetbyaddr();
1358 struct netent *getnetent();
1359 struct netent *nent;
1361 if (gimme != G_ARRAY) {
1362 astore(ary, ++sp, str_static(&str_undef));
1366 if (which == O_GNBYNAME) {
1367 char *name = str_get(ary->ary_array[sp+1]);
1369 nent = getnetbyname(name);
1371 else if (which == O_GNBYADDR) {
1372 STR *addrstr = ary->ary_array[sp+1];
1373 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1374 char *addr = str_get(addrstr);
1376 nent = getnetbyaddr(addr,addrtype);
1383 (void)astore(ary, ++sp, str = str_static(&str_no));
1384 str_set(str, nent->n_name);
1385 (void)astore(ary, ++sp, str = str_static(&str_no));
1386 for (elem = nent->n_aliases; *elem; elem++) {
1387 str_cat(str, *elem);
1389 str_ncat(str," ",1);
1391 (void)astore(ary, ++sp, str = str_static(&str_no));
1392 str_numset(str, (double)nent->n_addrtype);
1393 (void)astore(ary, ++sp, str = str_static(&str_no));
1394 str_numset(str, (double)nent->n_net);
1398 (void)astore(ary, ++sp, str_static(&str_no));
1406 do_gpent(which,gimme,arglast)
1411 register ARRAY *ary = stack;
1412 register int sp = arglast[0];
1413 register char **elem;
1415 struct protoent *getprotobyname();
1416 struct protoent *getprotobynumber();
1417 struct protoent *getprotoent();
1418 struct protoent *pent;
1420 if (gimme != G_ARRAY) {
1421 astore(ary, ++sp, str_static(&str_undef));
1425 if (which == O_GPBYNAME) {
1426 char *name = str_get(ary->ary_array[sp+1]);
1428 pent = getprotobyname(name);
1430 else if (which == O_GPBYNUMBER) {
1431 int proto = (int)str_gnum(ary->ary_array[sp+1]);
1433 pent = getprotobynumber(proto);
1436 pent = getprotoent();
1440 (void)astore(ary, ++sp, str = str_static(&str_no));
1441 str_set(str, pent->p_name);
1442 (void)astore(ary, ++sp, str = str_static(&str_no));
1443 for (elem = pent->p_aliases; *elem; elem++) {
1444 str_cat(str, *elem);
1446 str_ncat(str," ",1);
1448 (void)astore(ary, ++sp, str = str_static(&str_no));
1449 str_numset(str, (double)pent->p_proto);
1453 (void)astore(ary, ++sp, str_static(&str_no));
1461 do_gsent(which,gimme,arglast)
1466 register ARRAY *ary = stack;
1467 register int sp = arglast[0];
1468 register char **elem;
1470 struct servent *getservbyname();
1471 struct servent *getservbynumber();
1472 struct servent *getservent();
1473 struct servent *sent;
1475 if (gimme != G_ARRAY) {
1476 astore(ary, ++sp, str_static(&str_undef));
1480 if (which == O_GSBYNAME) {
1481 char *name = str_get(ary->ary_array[sp+1]);
1482 char *proto = str_get(ary->ary_array[sp+2]);
1484 if (proto && !*proto)
1487 sent = getservbyname(name,proto);
1489 else if (which == O_GSBYPORT) {
1490 int port = (int)str_gnum(ary->ary_array[sp+1]);
1491 char *proto = str_get(ary->ary_array[sp+2]);
1493 sent = getservbyport(port,proto);
1496 sent = getservent();
1499 (void)astore(ary, ++sp, str = str_static(&str_no));
1500 str_set(str, sent->s_name);
1501 (void)astore(ary, ++sp, str = str_static(&str_no));
1502 for (elem = sent->s_aliases; *elem; elem++) {
1503 str_cat(str, *elem);
1505 str_ncat(str," ",1);
1507 (void)astore(ary, ++sp, str = str_static(&str_no));
1509 str_numset(str, (double)ntohs(sent->s_port));
1511 str_numset(str, (double)(sent->s_port));
1513 (void)astore(ary, ++sp, str = str_static(&str_no));
1514 str_set(str, sent->s_proto);
1518 (void)astore(ary, ++sp, str_static(&str_no));
1526 do_select(gimme,arglast)
1530 register STR **st = stack->ary_array;
1531 register int sp = arglast[0];
1539 struct timeval timebuf;
1540 struct timeval *tbuf = &timebuf;
1542 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1548 #if BYTEORDER & 0xf0000
1549 #define ORDERBYTE (0x88888888 - BYTEORDER)
1551 #define ORDERBYTE (0x4444 - BYTEORDER)
1556 for (i = 1; i <= 3; i++) {
1557 j = st[sp+i]->str_cur;
1562 #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678
1563 growsize = maxlen; /* little endians can use vecs directly */
1571 masksize = NFDBITS / NBBY;
1573 masksize = sizeof(long); /* documented int, everyone seems to use long */
1575 growsize = maxlen + (masksize - (maxlen % masksize));
1576 Zero(&fd_sets[0], 4, char*);
1579 for (i = 1; i <= 3; i++) {
1584 str_grow(str,growsize);
1585 s = str_get(str) + j;
1586 while (++j <= growsize) {
1590 else if (str->str_ptr) {
1591 Safefree(str->str_ptr);
1592 str->str_ptr = Nullch;
1595 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1598 New(403, fd_sets[i], growsize, char);
1599 for (offset = 0; offset < growsize; offset += masksize) {
1600 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1601 fd_sets[i][j+offset] = s[(k % masksize) + offset];
1607 if (str->str_nok || str->str_pok) {
1608 value = str_gnum(str);
1611 timebuf.tv_sec = (long)value;
1612 value -= (double)timebuf.tv_sec;
1613 timebuf.tv_usec = (long)(value * 1000000.0);
1616 tbuf = Null(struct timeval*);
1618 #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678
1632 for (i = 1; i <= 3; i++) {
1636 for (offset = 0; offset < growsize; offset += masksize) {
1637 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1638 s[(k % masksize) + offset] = fd_sets[i][j+offset];
1644 st[++sp] = str_static(&str_no);
1645 str_numset(st[sp], (double)nfound);
1646 if (gimme == G_ARRAY && tbuf) {
1647 value = (double)(timebuf.tv_sec) +
1648 (double)(timebuf.tv_usec) / 1000000.0;
1649 st[++sp] = str_static(&str_no);
1650 str_numset(st[sp], value);
1656 do_spair(stab1, stab2, arglast)
1661 register STR **st = stack->ary_array;
1662 register int sp = arglast[2];
1663 register STIO *stio1;
1664 register STIO *stio2;
1665 int domain, type, protocol, fd[2];
1667 if (!stab1 || !stab2)
1670 stio1 = stab_io(stab1);
1671 stio2 = stab_io(stab2);
1673 stio1 = stab_io(stab1) = stio_new();
1674 else if (stio1->ifp)
1675 do_close(stab1,FALSE);
1677 stio2 = stab_io(stab2) = stio_new();
1678 else if (stio2->ifp)
1679 do_close(stab2,FALSE);
1681 domain = (int)str_gnum(st[++sp]);
1682 type = (int)str_gnum(st[++sp]);
1683 protocol = (int)str_gnum(st[++sp]);
1685 taintproper("Insecure dependency in socketpair");
1688 if (socketpair(domain,type,protocol,fd) < 0)
1691 fatal("Socketpair unimplemented");
1693 stio1->ifp = fdopen(fd[0], "r");
1694 stio1->ofp = fdopen(fd[0], "w");
1696 stio2->ifp = fdopen(fd[1], "r");
1697 stio2->ofp = fdopen(fd[1], "w");
1706 do_gpwent(which,gimme,arglast)
1712 register ARRAY *ary = stack;
1713 register int sp = arglast[0];
1714 register char **elem;
1716 struct passwd *getpwnam();
1717 struct passwd *getpwuid();
1718 struct passwd *getpwent();
1719 struct passwd *pwent;
1722 if (gimme != G_ARRAY) {
1723 astore(ary, ++sp, str_static(&str_undef));
1727 if (which == O_GPWNAM) {
1728 char *name = str_get(ary->ary_array[sp+1]);
1730 pwent = getpwnam(name);
1732 else if (which == O_GPWUID) {
1733 int uid = (int)str_gnum(ary->ary_array[sp+1]);
1735 pwent = getpwuid(uid);
1741 (void)astore(ary, ++sp, str = str_static(&str_no));
1742 str_set(str, pwent->pw_name);
1743 (void)astore(ary, ++sp, str = str_static(&str_no));
1744 str_set(str, pwent->pw_passwd);
1745 (void)astore(ary, ++sp, str = str_static(&str_no));
1746 str_numset(str, (double)pwent->pw_uid);
1747 (void)astore(ary, ++sp, str = str_static(&str_no));
1748 str_numset(str, (double)pwent->pw_gid);
1749 (void)astore(ary, ++sp, str = str_static(&str_no));
1751 str_numset(str, (double)pwent->pw_change);
1754 str_numset(str, (double)pwent->pw_quota);
1757 str_set(str, pwent->pw_age);
1761 (void)astore(ary, ++sp, str = str_static(&str_no));
1763 str_set(str,pwent->pw_class);
1765 str_set(str, pwent->pw_comment);
1767 (void)astore(ary, ++sp, str = str_static(&str_no));
1768 str_set(str, pwent->pw_gecos);
1769 (void)astore(ary, ++sp, str = str_static(&str_no));
1770 str_set(str, pwent->pw_dir);
1771 (void)astore(ary, ++sp, str = str_static(&str_no));
1772 str_set(str, pwent->pw_shell);
1774 (void)astore(ary, ++sp, str = str_static(&str_no));
1775 str_numset(str, (double)pwent->pw_expire);
1781 fatal("password routines not implemented");
1786 do_ggrent(which,gimme,arglast)
1792 register ARRAY *ary = stack;
1793 register int sp = arglast[0];
1794 register char **elem;
1796 struct group *getgrnam();
1797 struct group *getgrgid();
1798 struct group *getgrent();
1799 struct group *grent;
1802 if (gimme != G_ARRAY) {
1803 astore(ary, ++sp, str_static(&str_undef));
1807 if (which == O_GGRNAM) {
1808 char *name = str_get(ary->ary_array[sp+1]);
1810 grent = getgrnam(name);
1812 else if (which == O_GGRGID) {
1813 int gid = (int)str_gnum(ary->ary_array[sp+1]);
1815 grent = getgrgid(gid);
1821 (void)astore(ary, ++sp, str = str_static(&str_no));
1822 str_set(str, grent->gr_name);
1823 (void)astore(ary, ++sp, str = str_static(&str_no));
1824 str_set(str, grent->gr_passwd);
1825 (void)astore(ary, ++sp, str = str_static(&str_no));
1826 str_numset(str, (double)grent->gr_gid);
1827 (void)astore(ary, ++sp, str = str_static(&str_no));
1828 for (elem = grent->gr_mem; *elem; elem++) {
1829 str_cat(str, *elem);
1831 str_ncat(str," ",1);
1837 fatal("group routines not implemented");
1842 do_dirop(optype,stab,gimme,arglast)
1848 #if defined(DIRENT) && defined(READDIR)
1849 register ARRAY *ary = stack;
1850 register STR **st = ary->ary_array;
1851 register int sp = arglast[1];
1852 register STIO *stio;
1857 struct DIRENT *readdir();
1858 register struct DIRENT *dp;
1862 if (!(stio = stab_io(stab)))
1863 stio = stab_io(stab) = stio_new();
1864 if (!stio->dirp && optype != O_OPENDIR)
1870 closedir(stio->dirp);
1871 if (!(stio->dirp = opendir(str_get(st[sp+1]))))
1875 if (gimme == G_ARRAY) {
1877 while (dp = readdir(stio->dirp)) {
1879 (void)astore(ary,++sp,
1880 str_2static(str_make(dp->d_name,dp->d_namlen)));
1882 (void)astore(ary,++sp,
1883 str_2static(str_make(dp->d_name,0)));
1888 if (!(dp = readdir(stio->dirp)))
1890 st[sp] = str_static(&str_undef);
1892 str_nset(st[sp], dp->d_name, dp->d_namlen);
1894 str_set(st[sp], dp->d_name);
1899 st[sp] = str_static(&str_undef);
1900 str_numset(st[sp], (double)telldir(stio->dirp));
1903 st[sp] = str_static(&str_undef);
1904 along = (long)str_gnum(st[sp+1]);
1905 (void)seekdir(stio->dirp,along);
1908 st[sp] = str_static(&str_undef);
1909 (void)rewinddir(stio->dirp);
1912 st[sp] = str_static(&str_undef);
1913 (void)closedir(stio->dirp);
1920 st[sp] = &str_undef;
1924 fatal("Unimplemented directory operation");
1932 register STR **st = stack->ary_array;
1933 register int sp = arglast[1];
1934 register int items = arglast[2] - sp;
1937 register int tot = 0;
1941 for (st += ++sp; items--; st++)
1942 tainted |= (*st)->str_tainted;
1943 st = stack->ary_array;
1945 items = arglast[2] - sp;
1950 taintproper("Insecure dependency in chmod");
1954 val = (int)str_gnum(st[++sp]);
1956 if (chmod(str_get(st[++sp]),val))
1964 taintproper("Insecure dependency in chown");
1969 val = (int)str_gnum(st[++sp]);
1970 val2 = (int)str_gnum(st[++sp]);
1972 if (chown(str_get(st[++sp]),val,val2))
1981 taintproper("Insecure dependency in kill");
1985 s = str_get(st[++sp]);
1987 if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1989 if (!(val = whichsig(s)))
1990 fatal("Unrecognized signal name \"%s\"",s);
1993 val = (int)str_gnum(st[sp]);
1997 int proc = (int)str_gnum(st[++sp]);
1999 if (killpg(proc,val)) /* BSD */
2001 if (kill(-proc,val)) /* SYSV */
2008 if (kill((int)(str_gnum(st[++sp])),val))
2017 taintproper("Insecure dependency in unlink");
2021 s = str_get(st[++sp]);
2022 if (euid || unsafe) {
2026 else { /* don't let root wipe out directories without -U */
2028 if (lstat(s,&statbuf) < 0 ||
2030 if (stat(s,&statbuf) < 0 ||
2032 (statbuf.st_mode & S_IFMT) == S_IFDIR )
2043 taintproper("Insecure dependency in utime");
2047 struct utimbuf utbuf;
2055 Zero(&utbuf, sizeof utbuf, char);
2056 utbuf.actime = (long)str_gnum(st[++sp]); /* time accessed */
2057 utbuf.modtime = (long)str_gnum(st[++sp]); /* time modified */
2062 if (utime(str_get(st[++sp]),&utbuf))
2074 /* Do the permissions allow some operation? Assumes statcache already set. */
2077 cando(bit, effective, statbufp)
2080 register struct stat *statbufp;
2082 if ((effective ? euid : uid) == 0) { /* root is special */
2083 if (bit == S_IEXEC) {
2084 if (statbufp->st_mode & 0111 ||
2085 (statbufp->st_mode & S_IFMT) == S_IFDIR )
2089 return TRUE; /* root reads and writes anything */
2092 if (statbufp->st_uid == (effective ? euid : uid) ) {
2093 if (statbufp->st_mode & bit)
2094 return TRUE; /* ok as "user" */
2096 else if (ingroup((int)statbufp->st_gid,effective)) {
2097 if (statbufp->st_mode & bit >> 3)
2098 return TRUE; /* ok as "group" */
2100 else if (statbufp->st_mode & bit >> 6)
2101 return TRUE; /* ok as "other" */
2106 ingroup(testgid,effective)
2110 if (testgid == (effective ? egid : gid))
2117 GIDTYPE gary[NGROUPS];
2120 anum = getgroups(NGROUPS,gary);
2122 if (gary[anum] == testgid)