1 /* $Header: doio.c,v 3.0 89/10/18 15:10:54 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 89/10/18 15:10:54 lwall
18 #include <sys/socket.h>
38 int len = strlen(name);
39 register STIO *stio = stab_io(stab);
40 char *myname = savestr(name);
44 char mode[3]; /* stdio file mode ("r\0" or "r+\0") */
47 forkprocess = 1; /* assume true if no fork */
48 while (len && isspace(name[len-1]))
51 stio = stab_io(stab) = stio_new();
53 fd = fileno(stio->ifp);
54 if (stio->type == '|')
55 result = mypclose(stio->ifp);
56 else if (stio->ifp != stio->ofp) {
59 result = fclose(stio->ifp);
61 else if (stio->type != '-')
62 result = fclose(stio->ifp);
65 if (result == EOF && fd > 2)
66 fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
68 stio->ofp = stio->ifp = Nullfp;
70 if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
81 for (name++; isspace(*name); name++) ;
84 taintproper("Insecure dependency in piped open");
86 fp = mypopen(name,"w");
89 else if (*name == '>' && name[1] == '>') {
91 taintproper("Insecure dependency in open");
93 mode[0] = stio->type = 'a';
94 for (name += 2; isspace(*name); name++) ;
95 fp = fopen(name, mode);
98 else if (*name == '>' && name[1] == '&') {
100 taintproper("Insecure dependency in open");
102 for (name += 2; isspace(*name); name++) ;
106 stab = stabent(name,FALSE);
107 if (stab_io(stab) && stab_io(stab)->ifp) {
108 fd = fileno(stab_io(stab)->ifp);
109 stio->type = stab_io(stab)->type;
114 fp = fdopen(dup(fd),stio->type == 'a' ? "a" :
115 (stio->type == '<' ? "r" : "w") );
118 else if (*name == '>') {
120 taintproper("Insecure dependency in open");
122 for (name++; isspace(*name); name++) ;
123 if (strEQ(name,"-")) {
129 fp = fopen(name,mode);
135 for (name++; isspace(*name); name++) ;
136 if (strEQ(name,"-")) {
142 fp = fopen(name,mode);
145 else if (name[len-1] == '|') {
148 taintproper("Insecure dependency in piped open");
151 while (len && isspace(name[len-1]))
153 for (; isspace(*name); name++) ;
154 fp = mypopen(name,"r");
159 for (; isspace(*name); name++) ;
160 if (strEQ(name,"-")) {
165 fp = fopen(name,"r");
172 stio->type != '|' && stio->type != '-') {
173 if (fstat(fileno(fp),&statbuf) < 0) {
177 if ((statbuf.st_mode & S_IFMT) != S_IFREG &&
179 (statbuf.st_mode & S_IFMT) != S_IFSOCK &&
182 (statbuf.st_mode & S_IFMT) != S_IFFIFO &&
184 (statbuf.st_mode & S_IFMT) != S_IFCHR) {
201 int filemode,fileuid,filegid;
203 while (alen(stab_xarray(stab)) >= 0) {
204 str = ashift(stab_xarray(stab));
205 str_sset(stab_val(stab),str);
206 STABSET(stab_val(stab));
207 oldname = str_get(stab_val(stab));
208 if (do_open(stab,oldname)) {
211 taintproper("Insecure dependency in inplace open");
213 filemode = statbuf.st_mode;
214 fileuid = statbuf.st_uid;
215 filegid = statbuf.st_gid;
217 str_cat(str,inplace);
219 (void)rename(oldname,str->str_ptr);
221 (void)UNLINK(str->str_ptr);
222 (void)link(oldname,str->str_ptr);
223 (void)UNLINK(oldname);
227 (void)UNLINK(oldname);
231 str_cat(str,oldname);
232 errno = 0; /* in case sprintf set errno */
233 if (!do_open(argvoutstab,str->str_ptr))
234 fatal("Can't do inplace edit");
235 defoutstab = argvoutstab;
237 (void)fchmod(fileno(stab_io(argvoutstab)->ifp),filemode);
239 (void)chmod(oldname,filemode);
242 (void)fchown(fileno(stab_io(argvoutstab)->ifp),fileuid,filegid);
244 (void)chown(oldname,fileuid,filegid);
248 return stab_io(stab)->ifp;
251 fprintf(stderr,"Can't open %s\n",str_get(str));
255 (void)do_close(argvoutstab,FALSE);
256 defoutstab = stabent("STDOUT",TRUE);
262 do_close(stab,explicit)
267 register STIO *stio = stab_io(stab);
270 if (!stio) { /* never opened */
271 if (dowarn && explicit)
272 warn("Close on unopened file <%s>",stab_name(stab));
276 if (stio->type == '|') {
277 status = mypclose(stio->ifp);
278 retval = (status >= 0);
279 statusvalue = (unsigned)status & 0xffff;
281 else if (stio->type == '-')
284 if (stio->ofp && stio->ofp != stio->ifp) /* a socket */
286 retval = (fclose(stio->ifp) != EOF);
288 stio->ofp = stio->ifp = Nullfp;
303 if (!stab) { /* eof() */
305 stio = stab_io(argvstab);
310 stio = stab_io(stab);
317 #ifdef STDSTDIO /* (the code works without this) */
318 if (stio->ifp->_cnt > 0) /* cheat a little, since */
319 return FALSE; /* this is the most usual case */
322 ch = getc(stio->ifp);
324 (void)ungetc(ch, stio->ifp);
327 if (!stab) { /* not necessarily a real EOF yet? */
328 if (!nextargv(argvstab)) /* get another fp handy */
332 return TRUE; /* normal fp, definitely end of file */
346 stio = stab_io(stab);
347 if (!stio || !stio->ifp)
351 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
353 return ftell(stio->ifp);
357 warn("tell() on unopened file");
362 do_seek(stab, pos, whence)
372 stio = stab_io(stab);
373 if (!stio || !stio->ifp)
377 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
379 return fseek(stio->ifp, pos, whence) >= 0;
383 warn("seek() on unopened file");
388 do_ctl(optype,stab,func,argstr)
398 if (!stab || !argstr)
400 stio = stab_io(stab);
404 if (argstr->str_pok || !argstr->str_nok) {
405 if (!argstr->str_pok)
410 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
414 retval = IOCPARM_LEN(func); /* on BSDish systes we're safe */
416 retval = 256; /* otherwise guess at what's safe */
418 if (argstr->str_cur < retval) {
419 str_grow(argstr,retval+1);
420 argstr->str_cur = retval;
424 s[argstr->str_cur] = 17; /* a little sanity check here */
427 retval = (int)str_gnum(argstr);
428 s = (char*)retval; /* ouch */
432 if (optype == O_IOCTL)
433 retval = ioctl(fileno(stio->ifp), func, s);
436 retval = fcntl(fileno(stio->ifp), func, s);
438 fatal("fcntl is not implemented");
444 if (argstr->str_pok) {
445 if (s[argstr->str_cur] != 17)
446 fatal("Return value overflowed string");
447 s[argstr->str_cur] = 0; /* put our null back */
453 do_stat(str,arg,gimme,arglast)
459 register ARRAY *ary = stack;
460 register int sp = arglast[0] + 1;
464 if ((arg[1].arg_type & A_MASK) == A_WORD) {
465 tmpstab = arg[1].arg_ptr.arg_stab;
466 if (tmpstab != defstab) {
468 str_set(statname,"");
469 if (!stab_io(tmpstab) ||
470 fstat(fileno(stab_io(tmpstab)->ifp),&statcache) < 0) {
476 str_sset(statname,ary->ary_array[sp]);
479 if (arg->arg_type == O_LSTAT)
480 i = lstat(str_get(statname),&statcache);
483 i = stat(str_get(statname),&statcache);
488 if (gimme != G_ARRAY) {
490 str_sset(str,&str_yes);
492 str_sset(str,&str_undef);
494 ary->ary_array[sp] = str;
500 (void)astore(ary,++sp,
501 str_2static(str_nmake((double)statcache.st_dev)));
502 (void)astore(ary,++sp,
503 str_2static(str_nmake((double)statcache.st_ino)));
504 (void)astore(ary,++sp,
505 str_2static(str_nmake((double)statcache.st_mode)));
506 (void)astore(ary,++sp,
507 str_2static(str_nmake((double)statcache.st_nlink)));
508 (void)astore(ary,++sp,
509 str_2static(str_nmake((double)statcache.st_uid)));
510 (void)astore(ary,++sp,
511 str_2static(str_nmake((double)statcache.st_gid)));
512 (void)astore(ary,++sp,
513 str_2static(str_nmake((double)statcache.st_rdev)));
514 (void)astore(ary,++sp,
515 str_2static(str_nmake((double)statcache.st_size)));
516 (void)astore(ary,++sp,
517 str_2static(str_nmake((double)statcache.st_atime)));
518 (void)astore(ary,++sp,
519 str_2static(str_nmake((double)statcache.st_mtime)));
520 (void)astore(ary,++sp,
521 str_2static(str_nmake((double)statcache.st_ctime)));
523 (void)astore(ary,++sp,
524 str_2static(str_nmake((double)statcache.st_blksize)));
525 (void)astore(ary,++sp,
526 str_2static(str_nmake((double)statcache.st_blocks)));
528 (void)astore(ary,++sp,
529 str_2static(str_make("",0)));
530 (void)astore(ary,++sp,
531 str_2static(str_make("",0)));
534 (void)astore(ary,++sp,str_nmake(0.0));
541 looks_like_number(str)
550 send = s + str->str_cur;
555 if (*s == '+' || *s == '-')
563 else if (s == str->str_ptr)
569 if (*s == 'e' || *s == 'E') {
571 if (*s == '+' || *s == '-')
592 warn("print to unopened file");
598 ((str->str_nok && str->str_u.str_nval != 0.0)
599 || (looks_like_number(str) && str_gnum(str) != 0.0) ) )
600 fprintf(fp, ofmt, str->str_u.str_nval);
603 if (*tmps == 'S' && tmps[1] == 't' && tmps[2] == 'a' && tmps[3] == 'b'
604 && str->str_cur == sizeof(STBP) && strlen(tmps) < str->str_cur) {
605 tmps = stab_name(((STAB*)str)); /* a stab value, be nice */
606 str = ((STAB*)str)->str_magic;
609 if (str->str_cur && fwrite(tmps,1,str->str_cur,fp) == 0)
616 do_aprint(arg,fp,arglast)
621 register STR **st = stack->ary_array;
622 register int sp = arglast[1];
624 register int items = arglast[2] - sp;
628 warn("print to unopened file");
632 if (arg->arg_type == O_PRTF) {
633 do_sprintf(arg->arg_ptr.arg_str,items,st);
634 retval = do_print(arg->arg_ptr.arg_str,fp);
637 retval = (items <= 0);
638 for (; items > 0; items--,st++) {
639 if (retval && ofslen) {
640 if (fwrite(ofs, 1, ofslen, fp) == 0) {
645 if (!(retval = do_print(*st, fp)))
648 if (retval && orslen)
649 if (fwrite(ors, 1, orslen, fp) == 0)
662 if (arg[1].arg_type & A_DONT) {
663 stio = stab_io(arg[1].arg_ptr.arg_stab);
664 if (stio && stio->ifp) {
665 statstab = arg[1].arg_ptr.arg_stab;
666 str_set(statname,"");
667 return fstat(fileno(stio->ifp), &statcache);
670 if (arg[1].arg_ptr.arg_stab == defstab)
673 warn("Stat on unopened file <%s>",
674 stab_name(arg[1].arg_ptr.arg_stab));
676 str_set(statname,"");
682 str_sset(statname,str);
683 return stat(str_get(str),&statcache);
699 if (arg[1].arg_type & A_DONT) {
700 if (arg[1].arg_ptr.arg_stab == defstab) {
702 stio = stab_io(statstab);
705 goto really_filename;
709 statstab = arg[1].arg_ptr.arg_stab;
710 str_set(statname,"");
711 stio = stab_io(statstab);
713 if (stio && stio->ifp) {
715 fstat(fileno(stio->ifp),&statcache);
716 if (stio->ifp->_cnt <= 0) {
719 (void)ungetc(i,stio->ifp);
721 if (stio->ifp->_cnt <= 0) /* null file is anything */
723 len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base);
724 s = stio->ifp->_base;
726 fatal("-T and -B not implemented on filehandles\n");
731 warn("Test on unopened file <%s>",
732 stab_name(arg[1].arg_ptr.arg_stab));
738 str_sset(statname,str);
740 i = open(str_get(str),0);
744 len = read(i,tbuf,512);
745 if (len <= 0) /* null file is anything */
751 /* now scan s to look for textiness */
753 for (i = 0; i < len; i++,s++) {
754 if (!*s) { /* null never allowed in text */
761 *s != '\n' && *s != '\r' && *s != '\b' &&
762 *s != '\t' && *s != '\f' && *s != 27)
766 if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */
773 do_aexec(really,arglast)
777 register STR **st = stack->ary_array;
778 register int sp = arglast[1];
779 register int items = arglast[2] - sp;
785 New(401,argv, items+1, char*);
787 for (st += ++sp; items > 0; items--,st++) {
795 if (*argv[0] != '/') /* will execvp use PATH? */
796 taintenv(); /* testing IFS here is overkill, probably */
798 if (really && *(tmps = str_get(really)))
801 execvp(argv[0],argv);
818 taintproper("Insecure dependency in exec");
821 /* save an extra exec if possible */
823 if (csh > 0 && strnEQ(cmd,"/bin/csh -c",11)) {
841 execl("/bin/csh","csh", flags,ncmd,(char*)0);
848 /* see if there are shell metacharacters in it */
850 for (s = cmd; *s; s++) {
851 if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`\n",*s)) {
852 if (*s == '\n' && !s[1]) {
857 execl("/bin/sh","sh","-c",cmd,(char*)0);
861 New(402,argv, (s - cmd) / 2 + 2, char*);
865 while (*s && isspace(*s)) s++;
868 while (*s && !isspace(*s)) s++;
874 execvp(argv[0],argv);
875 if (errno == ENOEXEC) /* for system V NIH syndrome */
884 do_socket(stab, arglast)
888 register STR **st = stack->ary_array;
889 register int sp = arglast[1];
891 int domain, type, protocol, fd;
896 stio = stab_io(stab);
898 stio = stab_io(stab) = stio_new();
900 do_close(stab,FALSE);
902 domain = (int)str_gnum(st[++sp]);
903 type = (int)str_gnum(st[++sp]);
904 protocol = (int)str_gnum(st[++sp]);
906 taintproper("Insecure dependency in socket");
908 fd = socket(domain,type,protocol);
911 stio->ifp = fdopen(fd, "r"); /* stdio gets confused about sockets */
912 stio->ofp = fdopen(fd, "w");
919 do_bind(stab, arglast)
923 register STR **st = stack->ary_array;
924 register int sp = arglast[1];
931 stio = stab_io(stab);
932 if (!stio || !stio->ifp)
935 addr = str_get(st[++sp]);
937 taintproper("Insecure dependency in bind");
939 return bind(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
943 warn("bind() on closed fd");
949 do_connect(stab, arglast)
953 register STR **st = stack->ary_array;
954 register int sp = arglast[1];
961 stio = stab_io(stab);
962 if (!stio || !stio->ifp)
965 addr = str_get(st[++sp]);
967 taintproper("Insecure dependency in connect");
969 return connect(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
973 warn("connect() on closed fd");
979 do_listen(stab, arglast)
983 register STR **st = stack->ary_array;
984 register int sp = arglast[1];
991 stio = stab_io(stab);
992 if (!stio || !stio->ifp)
995 backlog = (int)str_gnum(st[++sp]);
996 return listen(fileno(stio->ifp), backlog) >= 0;
1000 warn("listen() on closed fd");
1005 do_accept(str, nstab, gstab)
1010 register STIO *nstio;
1011 register STIO *gstio;
1012 int len = sizeof buf;
1020 gstio = stab_io(gstab);
1021 nstio = stab_io(nstab);
1023 if (!gstio || !gstio->ifp)
1026 nstio = stab_io(nstab) = stio_new();
1027 else if (nstio->ifp)
1028 do_close(nstab,FALSE);
1030 fd = accept(fileno(gstio->ifp),buf,&len);
1033 nstio->ifp = fdopen(fd, "r");
1034 nstio->ofp = fdopen(fd, "w");
1037 str_nset(str, buf, len);
1042 warn("accept() on closed fd");
1044 str_sset(str,&str_undef);
1049 do_shutdown(stab, arglast)
1053 register STR **st = stack->ary_array;
1054 register int sp = arglast[1];
1055 register STIO *stio;
1061 stio = stab_io(stab);
1062 if (!stio || !stio->ifp)
1065 how = (int)str_gnum(st[++sp]);
1066 return shutdown(fileno(stio->ifp), how) >= 0;
1070 warn("shutdown() on closed fd");
1076 do_sopt(optype, stab, arglast)
1081 register STR **st = stack->ary_array;
1082 register int sp = arglast[1];
1083 register STIO *stio;
1091 stio = stab_io(stab);
1092 if (!stio || !stio->ifp)
1095 fd = fileno(stio->ifp);
1096 lvl = (int)str_gnum(st[sp+1]);
1097 optname = (int)str_gnum(st[sp+2]);
1100 st[sp] = str_2static(str_new(257));
1101 st[sp]->str_cur = 256;
1102 if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1107 if (setsockopt(fd, lvl, optname, st[sp]->str_ptr, st[sp]->str_cur) < 0)
1117 warn("shutdown() on closed fd");
1118 st[sp] = &str_undef;
1124 do_getsockname(optype, stab, arglast)
1129 register STR **st = stack->ary_array;
1130 register int sp = arglast[1];
1131 register STIO *stio;
1137 stio = stab_io(stab);
1138 if (!stio || !stio->ifp)
1141 st[sp] = str_2static(str_new(257));
1142 st[sp]->str_cur = 256;
1143 fd = fileno(stio->ifp);
1146 if (getsockname(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1150 if (getpeername(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1159 warn("shutdown() on closed fd");
1160 st[sp] = &str_undef;
1166 do_ghent(which,gimme,arglast)
1171 register ARRAY *ary = stack;
1172 register int sp = arglast[0];
1173 register char **elem;
1175 struct hostent *gethostbynam();
1176 struct hostent *gethostbyaddr();
1178 struct hostent *gethostent();
1180 struct hostent *hent;
1183 if (gimme != G_ARRAY) {
1184 astore(ary, ++sp, str_static(&str_undef));
1188 if (which == O_GHBYNAME) {
1189 char *name = str_get(ary->ary_array[sp+1]);
1191 hent = gethostbyname(name);
1193 else if (which == O_GHBYADDR) {
1194 STR *addrstr = ary->ary_array[sp+1];
1195 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1196 char *addr = str_get(addrstr);
1198 hent = gethostbyaddr(addr,addrstr->str_cur,addrtype);
1202 hent = gethostent();
1204 fatal("gethostent not implemented");
1208 (void)astore(ary, ++sp, str = str_static(&str_no));
1209 str_set(str, hent->h_name);
1210 (void)astore(ary, ++sp, str = str_static(&str_no));
1211 for (elem = hent->h_aliases; *elem; elem++) {
1212 str_cat(str, *elem);
1214 str_ncat(str," ",1);
1216 (void)astore(ary, ++sp, str = str_static(&str_no));
1217 str_numset(str, (double)hent->h_addrtype);
1218 (void)astore(ary, ++sp, str = str_static(&str_no));
1219 len = hent->h_length;
1220 str_numset(str, (double)len);
1222 for (elem = hent->h_addr_list; *elem; elem++) {
1223 (void)astore(ary, ++sp, str = str_static(&str_no));
1224 str_nset(str, *elem, len);
1227 (void)astore(ary, ++sp, str = str_static(&str_no));
1228 str_nset(str, hent->h_addr, len);
1233 (void)astore(ary, ++sp, str_static(&str_no));
1241 do_gnent(which,gimme,arglast)
1246 register ARRAY *ary = stack;
1247 register int sp = arglast[0];
1248 register char **elem;
1250 struct netent *getnetbyname();
1251 struct netent *getnetbyaddr();
1252 struct netent *getnetent();
1253 struct netent *nent;
1255 if (gimme != G_ARRAY) {
1256 astore(ary, ++sp, str_static(&str_undef));
1260 if (which == O_GNBYNAME) {
1261 char *name = str_get(ary->ary_array[sp+1]);
1263 nent = getnetbyname(name);
1265 else if (which == O_GNBYADDR) {
1266 STR *addrstr = ary->ary_array[sp+1];
1267 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1268 char *addr = str_get(addrstr);
1270 nent = getnetbyaddr(addr,addrtype);
1277 (void)astore(ary, ++sp, str = str_static(&str_no));
1278 str_set(str, nent->n_name);
1279 (void)astore(ary, ++sp, str = str_static(&str_no));
1280 for (elem = nent->n_aliases; *elem; elem++) {
1281 str_cat(str, *elem);
1283 str_ncat(str," ",1);
1285 (void)astore(ary, ++sp, str = str_static(&str_no));
1286 str_numset(str, (double)nent->n_addrtype);
1287 (void)astore(ary, ++sp, str = str_static(&str_no));
1288 str_numset(str, (double)nent->n_net);
1292 (void)astore(ary, ++sp, str_static(&str_no));
1300 do_gpent(which,gimme,arglast)
1305 register ARRAY *ary = stack;
1306 register int sp = arglast[0];
1307 register char **elem;
1309 struct protoent *getprotobyname();
1310 struct protoent *getprotobynumber();
1311 struct protoent *getprotoent();
1312 struct protoent *pent;
1314 if (gimme != G_ARRAY) {
1315 astore(ary, ++sp, str_static(&str_undef));
1319 if (which == O_GPBYNAME) {
1320 char *name = str_get(ary->ary_array[sp+1]);
1322 pent = getprotobyname(name);
1324 else if (which == O_GPBYNUMBER) {
1325 int proto = (int)str_gnum(ary->ary_array[sp+1]);
1327 pent = getprotobynumber(proto);
1330 pent = getprotoent();
1334 (void)astore(ary, ++sp, str = str_static(&str_no));
1335 str_set(str, pent->p_name);
1336 (void)astore(ary, ++sp, str = str_static(&str_no));
1337 for (elem = pent->p_aliases; *elem; elem++) {
1338 str_cat(str, *elem);
1340 str_ncat(str," ",1);
1342 (void)astore(ary, ++sp, str = str_static(&str_no));
1343 str_numset(str, (double)pent->p_proto);
1347 (void)astore(ary, ++sp, str_static(&str_no));
1355 do_gsent(which,gimme,arglast)
1360 register ARRAY *ary = stack;
1361 register int sp = arglast[0];
1362 register char **elem;
1364 struct servent *getservbyname();
1365 struct servent *getservbynumber();
1366 struct servent *getservent();
1367 struct servent *sent;
1369 if (gimme != G_ARRAY) {
1370 astore(ary, ++sp, str_static(&str_undef));
1374 if (which == O_GSBYNAME) {
1375 char *name = str_get(ary->ary_array[sp+1]);
1376 char *proto = str_get(ary->ary_array[sp+2]);
1378 if (proto && !*proto)
1381 sent = getservbyname(name,proto);
1383 else if (which == O_GSBYPORT) {
1384 int port = (int)str_gnum(ary->ary_array[sp+1]);
1385 char *proto = str_get(ary->ary_array[sp+2]);
1387 sent = getservbyport(port,proto);
1390 sent = getservent();
1393 (void)astore(ary, ++sp, str = str_static(&str_no));
1394 str_set(str, sent->s_name);
1395 (void)astore(ary, ++sp, str = str_static(&str_no));
1396 for (elem = sent->s_aliases; *elem; elem++) {
1397 str_cat(str, *elem);
1399 str_ncat(str," ",1);
1401 (void)astore(ary, ++sp, str = str_static(&str_no));
1403 str_numset(str, (double)ntohs(sent->s_port));
1405 str_numset(str, (double)(sent->s_port));
1407 (void)astore(ary, ++sp, str = str_static(&str_no));
1408 str_set(str, sent->s_proto);
1412 (void)astore(ary, ++sp, str_static(&str_no));
1420 do_select(gimme,arglast)
1424 register STR **st = stack->ary_array;
1425 register int sp = arglast[0];
1433 struct timeval timebuf;
1434 struct timeval *tbuf = &timebuf;
1436 for (i = 1; i <= 3; i++) {
1437 j = st[sp+i]->str_len;
1441 for (i = 1; i <= 3; i++) {
1446 str_grow(str,maxlen);
1447 s = str_get(str) + j;
1448 while (++j <= maxlen) {
1452 else if (str->str_ptr) {
1453 Safefree(str->str_ptr);
1454 str->str_ptr = Nullch;
1459 if (str->str_nok || str->str_pok) {
1460 value = str_gnum(str);
1463 timebuf.tv_sec = (long)value;
1464 value -= (double)timebuf.tv_sec;
1465 timebuf.tv_usec = (long)(value * 1000000.0);
1468 tbuf = Null(struct timeval*);
1477 st[++sp] = str_static(&str_no);
1478 str_numset(st[sp], (double)nfound);
1479 if (gimme == G_ARRAY && tbuf) {
1480 value = (double)(timebuf.tv_sec) +
1481 (double)(timebuf.tv_usec) / 1000000.0;
1482 st[++sp] = str_static(&str_no);
1483 str_numset(st[sp], value);
1489 do_spair(stab1, stab2, arglast)
1494 register STR **st = stack->ary_array;
1495 register int sp = arglast[2];
1496 register STIO *stio1;
1497 register STIO *stio2;
1498 int domain, type, protocol, fd[2];
1500 if (!stab1 || !stab2)
1503 stio1 = stab_io(stab1);
1504 stio2 = stab_io(stab2);
1506 stio1 = stab_io(stab1) = stio_new();
1507 else if (stio1->ifp)
1508 do_close(stab1,FALSE);
1510 stio2 = stab_io(stab2) = stio_new();
1511 else if (stio2->ifp)
1512 do_close(stab2,FALSE);
1514 domain = (int)str_gnum(st[++sp]);
1515 type = (int)str_gnum(st[++sp]);
1516 protocol = (int)str_gnum(st[++sp]);
1518 taintproper("Insecure dependency in socketpair");
1521 if (socketpair(domain,type,protocol,fd) < 0)
1524 fatal("Socketpair unimplemented");
1526 stio1->ifp = fdopen(fd[0], "r");
1527 stio1->ofp = fdopen(fd[0], "w");
1529 stio2->ifp = fdopen(fd[1], "r");
1530 stio2->ofp = fdopen(fd[1], "w");
1539 do_gpwent(which,gimme,arglast)
1545 register ARRAY *ary = stack;
1546 register int sp = arglast[0];
1547 register char **elem;
1549 struct passwd *getpwnam();
1550 struct passwd *getpwuid();
1551 struct passwd *getpwent();
1552 struct passwd *pwent;
1555 if (gimme != G_ARRAY) {
1556 astore(ary, ++sp, str_static(&str_undef));
1560 if (which == O_GPWNAM) {
1561 char *name = str_get(ary->ary_array[sp+1]);
1563 pwent = getpwnam(name);
1565 else if (which == O_GPWUID) {
1566 int uid = (int)str_gnum(ary->ary_array[sp+1]);
1568 pwent = getpwuid(uid);
1574 (void)astore(ary, ++sp, str = str_static(&str_no));
1575 str_set(str, pwent->pw_name);
1576 (void)astore(ary, ++sp, str = str_static(&str_no));
1577 str_set(str, pwent->pw_passwd);
1578 (void)astore(ary, ++sp, str = str_static(&str_no));
1579 str_numset(str, (double)pwent->pw_uid);
1580 (void)astore(ary, ++sp, str = str_static(&str_no));
1581 str_numset(str, (double)pwent->pw_gid);
1582 (void)astore(ary, ++sp, str = str_static(&str_no));
1584 str_numset(str, (double)pwent->pw_quota);
1587 str_set(str, pwent->pw_age);
1590 (void)astore(ary, ++sp, str = str_static(&str_no));
1591 str_set(str, pwent->pw_comment);
1592 (void)astore(ary, ++sp, str = str_static(&str_no));
1593 str_set(str, pwent->pw_gecos);
1594 (void)astore(ary, ++sp, str = str_static(&str_no));
1595 str_set(str, pwent->pw_dir);
1596 (void)astore(ary, ++sp, str = str_static(&str_no));
1597 str_set(str, pwent->pw_shell);
1602 fatal("password routines not implemented");
1607 do_ggrent(which,gimme,arglast)
1613 register ARRAY *ary = stack;
1614 register int sp = arglast[0];
1615 register char **elem;
1617 struct group *getgrnam();
1618 struct group *getgrgid();
1619 struct group *getgrent();
1620 struct group *grent;
1623 if (gimme != G_ARRAY) {
1624 astore(ary, ++sp, str_static(&str_undef));
1628 if (which == O_GGRNAM) {
1629 char *name = str_get(ary->ary_array[sp+1]);
1631 grent = getgrnam(name);
1633 else if (which == O_GGRGID) {
1634 int gid = (int)str_gnum(ary->ary_array[sp+1]);
1636 grent = getgrgid(gid);
1642 (void)astore(ary, ++sp, str = str_static(&str_no));
1643 str_set(str, grent->gr_name);
1644 (void)astore(ary, ++sp, str = str_static(&str_no));
1645 str_set(str, grent->gr_passwd);
1646 (void)astore(ary, ++sp, str = str_static(&str_no));
1647 str_numset(str, (double)grent->gr_gid);
1648 (void)astore(ary, ++sp, str = str_static(&str_no));
1649 for (elem = grent->gr_mem; *elem; elem++) {
1650 str_cat(str, *elem);
1652 str_ncat(str," ",1);
1658 fatal("group routines not implemented");
1663 do_dirop(optype,stab,gimme,arglast)
1670 register ARRAY *ary = stack;
1671 register STR **st = ary->ary_array;
1672 register int sp = arglast[1];
1673 register STIO *stio;
1676 struct DIRENT *readdir();
1677 register struct DIRENT *dp;
1681 if (!(stio = stab_io(stab)))
1682 stio = stab_io(stab) = stio_new();
1683 if (!stio->dirp && optype != O_OPENDIR)
1689 closedir(stio->dirp);
1690 if (!(stio->dirp = opendir(str_get(st[sp+1]))))
1694 if (gimme == G_ARRAY) {
1696 while (dp = readdir(stio->dirp)) {
1698 (void)astore(ary,++sp,
1699 str_2static(str_make(dp->d_name,dp->d_namlen)));
1701 (void)astore(ary,++sp,
1702 str_2static(str_make(dp->d_name,0)));
1707 if (!(dp = readdir(stio->dirp)))
1709 st[sp] = str_static(&str_undef);
1711 str_nset(st[sp], dp->d_name, dp->d_namlen);
1713 str_set(st[sp], dp->d_name);
1718 st[sp] = str_static(&str_undef);
1719 str_numset(st[sp], (double)telldir(stio->dirp));
1722 st[sp] = str_static(&str_undef);
1723 along = (long)str_gnum(st[sp+1]);
1724 (void)seekdir(stio->dirp,along);
1727 st[sp] = str_static(&str_undef);
1728 (void)rewinddir(stio->dirp);
1731 st[sp] = str_static(&str_undef);
1732 (void)closedir(stio->dirp);
1739 st[sp] = &str_undef;
1743 fatal("Unimplemented directory operation");
1751 register STR **st = stack->ary_array;
1752 register int sp = arglast[1];
1753 register int items = arglast[2] - sp;
1756 register int tot = 0;
1760 for (st += ++sp; items--; st++)
1761 tainted |= (*st)->str_tainted;
1762 st = stack->ary_array;
1764 items = arglast[2] - sp;
1769 taintproper("Insecure dependency in chmod");
1773 val = (int)str_gnum(st[++sp]);
1775 if (chmod(str_get(st[++sp]),val))
1782 taintproper("Insecure dependency in chown");
1787 val = (int)str_gnum(st[++sp]);
1788 val2 = (int)str_gnum(st[++sp]);
1790 if (chown(str_get(st[++sp]),val,val2))
1797 taintproper("Insecure dependency in kill");
1801 s = str_get(st[++sp]);
1803 if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1805 if (!(val = whichsig(s)))
1806 fatal("Unrecognized signal name \"%s\"",s);
1809 val = (int)str_gnum(st[sp]);
1813 int proc = (int)str_gnum(st[++sp]);
1815 if (killpg(proc,val)) /* BSD */
1817 if (kill(-proc,val)) /* SYSV */
1824 if (kill((int)(str_gnum(st[++sp])),val))
1832 taintproper("Insecure dependency in unlink");
1836 s = str_get(st[++sp]);
1837 if (euid || unsafe) {
1841 else { /* don't let root wipe out directories without -U */
1843 if (lstat(s,&statbuf) < 0 ||
1845 if (stat(s,&statbuf) < 0 ||
1847 (statbuf.st_mode & S_IFMT) == S_IFDIR )
1858 taintproper("Insecure dependency in utime");
1866 utbuf.atime = (long)str_gnum(st[++sp]); /* time accessed */
1867 utbuf.mtime = (long)str_gnum(st[++sp]); /* time modified */
1872 if (utime(str_get(st[++sp]),&utbuf))
1884 /* Do the permissions allow some operation? Assumes statcache already set. */
1887 cando(bit, effective, statbufp)
1890 register struct stat *statbufp;
1892 if ((effective ? euid : uid) == 0) { /* root is special */
1893 if (bit == S_IEXEC) {
1894 if (statbufp->st_mode & 0111 ||
1895 (statbufp->st_mode & S_IFMT) == S_IFDIR )
1899 return TRUE; /* root reads and writes anything */
1902 if (statbufp->st_uid == (effective ? euid : uid) ) {
1903 if (statbufp->st_mode & bit)
1904 return TRUE; /* ok as "user" */
1906 else if (ingroup((int)statbufp->st_gid,effective)) {
1907 if (statbufp->st_mode & bit >> 3)
1908 return TRUE; /* ok as "group" */
1910 else if (statbufp->st_mode & bit >> 6)
1911 return TRUE; /* ok as "other" */
1916 ingroup(testgid,effective)
1920 if (testgid == (effective ? egid : gid))
1927 GIDTYPE gary[NGROUPS];
1930 anum = getgroups(NGROUPS,gary);
1932 if (gary[anum] == testgid)