1 /* $Header: doio.c,v 3.0.1.2 89/11/11 04:25:51 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.2 89/11/11 04:25:51 lwall
10 * patch2: orthogonalized the file modes some so we can have <& +<& etc.
11 * patch2: do_open() now detects sockets passed to process from parent
12 * patch2: fd's above 2 are now closed on exec
13 * patch2: csh code can now use csh from other than /bin
14 * patch2: getsockopt, get{sock,peer}name didn't define result properly
15 * patch2: warn("shutdown") was replicated
16 * patch2: gethostbyname was misdeclared
17 * patch2: telldir() is sometimes a macro
19 * Revision 3.0.1.1 89/10/26 23:10:05 lwall
20 * patch1: Configure now checks for BSD shadow passwords
22 * Revision 3.0 89/10/18 15:10:54 lwall
31 #include <sys/socket.h>
51 int len = strlen(name);
52 register STIO *stio = stab_io(stab);
53 char *myname = savestr(name);
57 char mode[3]; /* stdio file mode ("r\0" or "r+\0") */
60 forkprocess = 1; /* assume true if no fork */
61 while (len && isspace(name[len-1]))
64 stio = stab_io(stab) = stio_new();
66 fd = fileno(stio->ifp);
67 if (stio->type == '|')
68 result = mypclose(stio->ifp);
69 else if (stio->ifp != stio->ofp) {
72 result = fclose(stio->ifp);
74 else if (stio->type != '-')
75 result = fclose(stio->ifp);
78 if (result == EOF && fd > 2)
79 fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
81 stio->ofp = stio->ifp = Nullfp;
83 if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
94 for (name++; isspace(*name); name++) ;
97 taintproper("Insecure dependency in piped open");
99 fp = mypopen(name,"w");
102 else if (*name == '>') {
104 taintproper("Insecure dependency in open");
108 mode[0] = stio->type = 'a';
117 while (isspace(*name))
122 stab = stabent(name,FALSE);
123 if (!stab || !stab_io(stab))
125 if (stab_io(stab) && stab_io(stab)->ifp) {
126 fd = fileno(stab_io(stab)->ifp);
127 if (stab_io(stab)->type == 's')
133 fp = fdopen(dup(fd),mode);
136 while (isspace(*name))
138 if (strEQ(name,"-")) {
143 fp = fopen(name,mode);
151 while (isspace(*name))
155 if (strEQ(name,"-")) {
160 fp = fopen(name,mode);
162 else if (name[len-1] == '|') {
165 taintproper("Insecure dependency in piped open");
168 while (len && isspace(name[len-1]))
170 for (; isspace(*name); name++) ;
171 fp = mypopen(name,"r");
176 for (; isspace(*name); name++) ;
177 if (strEQ(name,"-")) {
182 fp = fopen(name,"r");
189 stio->type != '|' && stio->type != '-') {
190 if (fstat(fileno(fp),&statbuf) < 0) {
194 result = (statbuf.st_mode & S_IFMT);
195 if (result != S_IFREG &&
197 result != S_IFSOCK &&
200 result != S_IFFIFO &&
205 result != 0 && /* socket? */
211 if (result == S_IFSOCK || result == 0)
212 stio->type = 's'; /* in case a socket was passed in to us */
215 #if defined(FCNTL) && defined(F_SETFD)
222 if (stio->type != 's')
225 stio->ofp = fdopen(fileno(fp),"w");
236 int filemode,fileuid,filegid;
238 while (alen(stab_xarray(stab)) >= 0) {
239 str = ashift(stab_xarray(stab));
240 str_sset(stab_val(stab),str);
241 STABSET(stab_val(stab));
242 oldname = str_get(stab_val(stab));
243 if (do_open(stab,oldname)) {
246 taintproper("Insecure dependency in inplace open");
248 filemode = statbuf.st_mode;
249 fileuid = statbuf.st_uid;
250 filegid = statbuf.st_gid;
252 str_cat(str,inplace);
254 (void)rename(oldname,str->str_ptr);
256 (void)UNLINK(str->str_ptr);
257 (void)link(oldname,str->str_ptr);
258 (void)UNLINK(oldname);
262 (void)UNLINK(oldname);
266 str_cat(str,oldname);
267 errno = 0; /* in case sprintf set errno */
268 if (!do_open(argvoutstab,str->str_ptr))
269 fatal("Can't do inplace edit");
270 defoutstab = argvoutstab;
272 (void)fchmod(fileno(stab_io(argvoutstab)->ifp),filemode);
274 (void)chmod(oldname,filemode);
277 (void)fchown(fileno(stab_io(argvoutstab)->ifp),fileuid,filegid);
279 (void)chown(oldname,fileuid,filegid);
283 return stab_io(stab)->ifp;
286 fprintf(stderr,"Can't open %s\n",str_get(str));
290 (void)do_close(argvoutstab,FALSE);
291 defoutstab = stabent("STDOUT",TRUE);
297 do_close(stab,explicit)
302 register STIO *stio = stab_io(stab);
305 if (!stio) { /* never opened */
306 if (dowarn && explicit)
307 warn("Close on unopened file <%s>",stab_name(stab));
311 if (stio->type == '|') {
312 status = mypclose(stio->ifp);
313 retval = (status >= 0);
314 statusvalue = (unsigned)status & 0xffff;
316 else if (stio->type == '-')
319 if (stio->ofp && stio->ofp != stio->ifp) /* a socket */
321 retval = (fclose(stio->ifp) != EOF);
323 stio->ofp = stio->ifp = Nullfp;
338 if (!stab) { /* eof() */
340 stio = stab_io(argvstab);
345 stio = stab_io(stab);
352 #ifdef STDSTDIO /* (the code works without this) */
353 if (stio->ifp->_cnt > 0) /* cheat a little, since */
354 return FALSE; /* this is the most usual case */
357 ch = getc(stio->ifp);
359 (void)ungetc(ch, stio->ifp);
362 if (!stab) { /* not necessarily a real EOF yet? */
363 if (!nextargv(argvstab)) /* get another fp handy */
367 return TRUE; /* normal fp, definitely end of file */
381 stio = stab_io(stab);
382 if (!stio || !stio->ifp)
386 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
388 return ftell(stio->ifp);
392 warn("tell() on unopened file");
397 do_seek(stab, pos, whence)
407 stio = stab_io(stab);
408 if (!stio || !stio->ifp)
412 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
414 return fseek(stio->ifp, pos, whence) >= 0;
418 warn("seek() on unopened file");
423 do_ctl(optype,stab,func,argstr)
433 if (!stab || !argstr)
435 stio = stab_io(stab);
439 if (argstr->str_pok || !argstr->str_nok) {
440 if (!argstr->str_pok)
445 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
449 retval = IOCPARM_LEN(func); /* on BSDish systes we're safe */
451 retval = 256; /* otherwise guess at what's safe */
453 if (argstr->str_cur < retval) {
454 str_grow(argstr,retval+1);
455 argstr->str_cur = retval;
459 s[argstr->str_cur] = 17; /* a little sanity check here */
462 retval = (int)str_gnum(argstr);
463 s = (char*)retval; /* ouch */
467 if (optype == O_IOCTL)
468 retval = ioctl(fileno(stio->ifp), func, s);
471 retval = fcntl(fileno(stio->ifp), func, s);
473 fatal("fcntl is not implemented");
479 if (argstr->str_pok) {
480 if (s[argstr->str_cur] != 17)
481 fatal("Return value overflowed string");
482 s[argstr->str_cur] = 0; /* put our null back */
488 do_stat(str,arg,gimme,arglast)
494 register ARRAY *ary = stack;
495 register int sp = arglast[0] + 1;
499 if ((arg[1].arg_type & A_MASK) == A_WORD) {
500 tmpstab = arg[1].arg_ptr.arg_stab;
501 if (tmpstab != defstab) {
503 str_set(statname,"");
504 if (!stab_io(tmpstab) ||
505 fstat(fileno(stab_io(tmpstab)->ifp),&statcache) < 0) {
511 str_sset(statname,ary->ary_array[sp]);
514 if (arg->arg_type == O_LSTAT)
515 i = lstat(str_get(statname),&statcache);
518 i = stat(str_get(statname),&statcache);
523 if (gimme != G_ARRAY) {
525 str_sset(str,&str_yes);
527 str_sset(str,&str_undef);
529 ary->ary_array[sp] = str;
535 (void)astore(ary,++sp,
536 str_2static(str_nmake((double)statcache.st_dev)));
537 (void)astore(ary,++sp,
538 str_2static(str_nmake((double)statcache.st_ino)));
539 (void)astore(ary,++sp,
540 str_2static(str_nmake((double)statcache.st_mode)));
541 (void)astore(ary,++sp,
542 str_2static(str_nmake((double)statcache.st_nlink)));
543 (void)astore(ary,++sp,
544 str_2static(str_nmake((double)statcache.st_uid)));
545 (void)astore(ary,++sp,
546 str_2static(str_nmake((double)statcache.st_gid)));
547 (void)astore(ary,++sp,
548 str_2static(str_nmake((double)statcache.st_rdev)));
549 (void)astore(ary,++sp,
550 str_2static(str_nmake((double)statcache.st_size)));
551 (void)astore(ary,++sp,
552 str_2static(str_nmake((double)statcache.st_atime)));
553 (void)astore(ary,++sp,
554 str_2static(str_nmake((double)statcache.st_mtime)));
555 (void)astore(ary,++sp,
556 str_2static(str_nmake((double)statcache.st_ctime)));
558 (void)astore(ary,++sp,
559 str_2static(str_nmake((double)statcache.st_blksize)));
560 (void)astore(ary,++sp,
561 str_2static(str_nmake((double)statcache.st_blocks)));
563 (void)astore(ary,++sp,
564 str_2static(str_make("",0)));
565 (void)astore(ary,++sp,
566 str_2static(str_make("",0)));
569 (void)astore(ary,++sp,str_nmake(0.0));
576 looks_like_number(str)
585 send = s + str->str_cur;
590 if (*s == '+' || *s == '-')
598 else if (s == str->str_ptr)
604 if (*s == 'e' || *s == 'E') {
606 if (*s == '+' || *s == '-')
627 warn("print to unopened file");
633 ((str->str_nok && str->str_u.str_nval != 0.0)
634 || (looks_like_number(str) && str_gnum(str) != 0.0) ) )
635 fprintf(fp, ofmt, str->str_u.str_nval);
638 if (*tmps == 'S' && tmps[1] == 't' && tmps[2] == 'a' && tmps[3] == 'b'
639 && str->str_cur == sizeof(STBP) && strlen(tmps) < str->str_cur) {
640 tmps = stab_name(((STAB*)str)); /* a stab value, be nice */
641 str = ((STAB*)str)->str_magic;
644 if (str->str_cur && fwrite(tmps,1,str->str_cur,fp) == 0)
651 do_aprint(arg,fp,arglast)
656 register STR **st = stack->ary_array;
657 register int sp = arglast[1];
659 register int items = arglast[2] - sp;
663 warn("print to unopened file");
667 if (arg->arg_type == O_PRTF) {
668 do_sprintf(arg->arg_ptr.arg_str,items,st);
669 retval = do_print(arg->arg_ptr.arg_str,fp);
672 retval = (items <= 0);
673 for (; items > 0; items--,st++) {
674 if (retval && ofslen) {
675 if (fwrite(ofs, 1, ofslen, fp) == 0) {
680 if (!(retval = do_print(*st, fp)))
683 if (retval && orslen)
684 if (fwrite(ors, 1, orslen, fp) == 0)
697 if (arg[1].arg_type & A_DONT) {
698 stio = stab_io(arg[1].arg_ptr.arg_stab);
699 if (stio && stio->ifp) {
700 statstab = arg[1].arg_ptr.arg_stab;
701 str_set(statname,"");
702 return fstat(fileno(stio->ifp), &statcache);
705 if (arg[1].arg_ptr.arg_stab == defstab)
708 warn("Stat on unopened file <%s>",
709 stab_name(arg[1].arg_ptr.arg_stab));
711 str_set(statname,"");
717 str_sset(statname,str);
718 return stat(str_get(str),&statcache);
734 if (arg[1].arg_type & A_DONT) {
735 if (arg[1].arg_ptr.arg_stab == defstab) {
737 stio = stab_io(statstab);
740 goto really_filename;
744 statstab = arg[1].arg_ptr.arg_stab;
745 str_set(statname,"");
746 stio = stab_io(statstab);
748 if (stio && stio->ifp) {
750 fstat(fileno(stio->ifp),&statcache);
751 if (stio->ifp->_cnt <= 0) {
754 (void)ungetc(i,stio->ifp);
756 if (stio->ifp->_cnt <= 0) /* null file is anything */
758 len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base);
759 s = stio->ifp->_base;
761 fatal("-T and -B not implemented on filehandles\n");
766 warn("Test on unopened file <%s>",
767 stab_name(arg[1].arg_ptr.arg_stab));
773 str_sset(statname,str);
775 i = open(str_get(str),0);
779 len = read(i,tbuf,512);
780 if (len <= 0) /* null file is anything */
786 /* now scan s to look for textiness */
788 for (i = 0; i < len; i++,s++) {
789 if (!*s) { /* null never allowed in text */
796 *s != '\n' && *s != '\r' && *s != '\b' &&
797 *s != '\t' && *s != '\f' && *s != 27)
801 if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */
808 do_aexec(really,arglast)
812 register STR **st = stack->ary_array;
813 register int sp = arglast[1];
814 register int items = arglast[2] - sp;
820 New(401,argv, items+1, char*);
822 for (st += ++sp; items > 0; items--,st++) {
830 if (*argv[0] != '/') /* will execvp use PATH? */
831 taintenv(); /* testing IFS here is overkill, probably */
833 if (really && *(tmps = str_get(really)))
836 execvp(argv[0],argv);
853 taintproper("Insecure dependency in exec");
856 /* save an extra exec if possible */
859 if (strnEQ(cmd,cshname,cshlen) && strnEQ(cmd+cshlen," -c",3)) {
877 execl(cshname,"csh", flags,ncmd,(char*)0);
885 /* see if there are shell metacharacters in it */
887 for (s = cmd; *s; s++) {
888 if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`\n",*s)) {
889 if (*s == '\n' && !s[1]) {
894 execl("/bin/sh","sh","-c",cmd,(char*)0);
898 New(402,argv, (s - cmd) / 2 + 2, char*);
902 while (*s && isspace(*s)) s++;
905 while (*s && !isspace(*s)) s++;
911 execvp(argv[0],argv);
912 if (errno == ENOEXEC) /* for system V NIH syndrome */
921 do_socket(stab, arglast)
925 register STR **st = stack->ary_array;
926 register int sp = arglast[1];
928 int domain, type, protocol, fd;
933 stio = stab_io(stab);
935 stio = stab_io(stab) = stio_new();
937 do_close(stab,FALSE);
939 domain = (int)str_gnum(st[++sp]);
940 type = (int)str_gnum(st[++sp]);
941 protocol = (int)str_gnum(st[++sp]);
943 taintproper("Insecure dependency in socket");
945 fd = socket(domain,type,protocol);
948 stio->ifp = fdopen(fd, "r"); /* stdio gets confused about sockets */
949 stio->ofp = fdopen(fd, "w");
956 do_bind(stab, arglast)
960 register STR **st = stack->ary_array;
961 register int sp = arglast[1];
968 stio = stab_io(stab);
969 if (!stio || !stio->ifp)
972 addr = str_get(st[++sp]);
974 taintproper("Insecure dependency in bind");
976 return bind(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
980 warn("bind() on closed fd");
986 do_connect(stab, arglast)
990 register STR **st = stack->ary_array;
991 register int sp = arglast[1];
998 stio = stab_io(stab);
999 if (!stio || !stio->ifp)
1002 addr = str_get(st[++sp]);
1004 taintproper("Insecure dependency in connect");
1006 return connect(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
1010 warn("connect() on closed fd");
1016 do_listen(stab, arglast)
1020 register STR **st = stack->ary_array;
1021 register int sp = arglast[1];
1022 register STIO *stio;
1028 stio = stab_io(stab);
1029 if (!stio || !stio->ifp)
1032 backlog = (int)str_gnum(st[++sp]);
1033 return listen(fileno(stio->ifp), backlog) >= 0;
1037 warn("listen() on closed fd");
1042 do_accept(str, nstab, gstab)
1047 register STIO *nstio;
1048 register STIO *gstio;
1049 int len = sizeof buf;
1057 gstio = stab_io(gstab);
1058 nstio = stab_io(nstab);
1060 if (!gstio || !gstio->ifp)
1063 nstio = stab_io(nstab) = stio_new();
1064 else if (nstio->ifp)
1065 do_close(nstab,FALSE);
1067 fd = accept(fileno(gstio->ifp),buf,&len);
1070 nstio->ifp = fdopen(fd, "r");
1071 nstio->ofp = fdopen(fd, "w");
1074 str_nset(str, buf, len);
1079 warn("accept() on closed fd");
1081 str_sset(str,&str_undef);
1086 do_shutdown(stab, arglast)
1090 register STR **st = stack->ary_array;
1091 register int sp = arglast[1];
1092 register STIO *stio;
1098 stio = stab_io(stab);
1099 if (!stio || !stio->ifp)
1102 how = (int)str_gnum(st[++sp]);
1103 return shutdown(fileno(stio->ifp), how) >= 0;
1107 warn("shutdown() on closed fd");
1113 do_sopt(optype, stab, arglast)
1118 register STR **st = stack->ary_array;
1119 register int sp = arglast[1];
1120 register STIO *stio;
1128 stio = stab_io(stab);
1129 if (!stio || !stio->ifp)
1132 fd = fileno(stio->ifp);
1133 lvl = (int)str_gnum(st[sp+1]);
1134 optname = (int)str_gnum(st[sp+2]);
1137 st[sp] = str_2static(str_new(257));
1138 st[sp]->str_cur = 256;
1139 st[sp]->str_pok = 1;
1140 if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1145 if (setsockopt(fd, lvl, optname, st[sp]->str_ptr, st[sp]->str_cur) < 0)
1155 warn("[gs]etsockopt() on closed fd");
1156 st[sp] = &str_undef;
1162 do_getsockname(optype, stab, arglast)
1167 register STR **st = stack->ary_array;
1168 register int sp = arglast[1];
1169 register STIO *stio;
1175 stio = stab_io(stab);
1176 if (!stio || !stio->ifp)
1179 st[sp] = str_2static(str_new(257));
1180 st[sp]->str_cur = 256;
1181 st[sp]->str_pok = 1;
1182 fd = fileno(stio->ifp);
1185 if (getsockname(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1189 if (getpeername(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1198 warn("get{sock,peer}name() on closed fd");
1199 st[sp] = &str_undef;
1205 do_ghent(which,gimme,arglast)
1210 register ARRAY *ary = stack;
1211 register int sp = arglast[0];
1212 register char **elem;
1214 struct hostent *gethostbyname();
1215 struct hostent *gethostbyaddr();
1217 struct hostent *gethostent();
1219 struct hostent *hent;
1222 if (gimme != G_ARRAY) {
1223 astore(ary, ++sp, str_static(&str_undef));
1227 if (which == O_GHBYNAME) {
1228 char *name = str_get(ary->ary_array[sp+1]);
1230 hent = gethostbyname(name);
1232 else if (which == O_GHBYADDR) {
1233 STR *addrstr = ary->ary_array[sp+1];
1234 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1235 char *addr = str_get(addrstr);
1237 hent = gethostbyaddr(addr,addrstr->str_cur,addrtype);
1241 hent = gethostent();
1243 fatal("gethostent not implemented");
1247 (void)astore(ary, ++sp, str = str_static(&str_no));
1248 str_set(str, hent->h_name);
1249 (void)astore(ary, ++sp, str = str_static(&str_no));
1250 for (elem = hent->h_aliases; *elem; elem++) {
1251 str_cat(str, *elem);
1253 str_ncat(str," ",1);
1255 (void)astore(ary, ++sp, str = str_static(&str_no));
1256 str_numset(str, (double)hent->h_addrtype);
1257 (void)astore(ary, ++sp, str = str_static(&str_no));
1258 len = hent->h_length;
1259 str_numset(str, (double)len);
1261 for (elem = hent->h_addr_list; *elem; elem++) {
1262 (void)astore(ary, ++sp, str = str_static(&str_no));
1263 str_nset(str, *elem, len);
1266 (void)astore(ary, ++sp, str = str_static(&str_no));
1267 str_nset(str, hent->h_addr, len);
1272 (void)astore(ary, ++sp, str_static(&str_no));
1280 do_gnent(which,gimme,arglast)
1285 register ARRAY *ary = stack;
1286 register int sp = arglast[0];
1287 register char **elem;
1289 struct netent *getnetbyname();
1290 struct netent *getnetbyaddr();
1291 struct netent *getnetent();
1292 struct netent *nent;
1294 if (gimme != G_ARRAY) {
1295 astore(ary, ++sp, str_static(&str_undef));
1299 if (which == O_GNBYNAME) {
1300 char *name = str_get(ary->ary_array[sp+1]);
1302 nent = getnetbyname(name);
1304 else if (which == O_GNBYADDR) {
1305 STR *addrstr = ary->ary_array[sp+1];
1306 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1307 char *addr = str_get(addrstr);
1309 nent = getnetbyaddr(addr,addrtype);
1316 (void)astore(ary, ++sp, str = str_static(&str_no));
1317 str_set(str, nent->n_name);
1318 (void)astore(ary, ++sp, str = str_static(&str_no));
1319 for (elem = nent->n_aliases; *elem; elem++) {
1320 str_cat(str, *elem);
1322 str_ncat(str," ",1);
1324 (void)astore(ary, ++sp, str = str_static(&str_no));
1325 str_numset(str, (double)nent->n_addrtype);
1326 (void)astore(ary, ++sp, str = str_static(&str_no));
1327 str_numset(str, (double)nent->n_net);
1331 (void)astore(ary, ++sp, str_static(&str_no));
1339 do_gpent(which,gimme,arglast)
1344 register ARRAY *ary = stack;
1345 register int sp = arglast[0];
1346 register char **elem;
1348 struct protoent *getprotobyname();
1349 struct protoent *getprotobynumber();
1350 struct protoent *getprotoent();
1351 struct protoent *pent;
1353 if (gimme != G_ARRAY) {
1354 astore(ary, ++sp, str_static(&str_undef));
1358 if (which == O_GPBYNAME) {
1359 char *name = str_get(ary->ary_array[sp+1]);
1361 pent = getprotobyname(name);
1363 else if (which == O_GPBYNUMBER) {
1364 int proto = (int)str_gnum(ary->ary_array[sp+1]);
1366 pent = getprotobynumber(proto);
1369 pent = getprotoent();
1373 (void)astore(ary, ++sp, str = str_static(&str_no));
1374 str_set(str, pent->p_name);
1375 (void)astore(ary, ++sp, str = str_static(&str_no));
1376 for (elem = pent->p_aliases; *elem; elem++) {
1377 str_cat(str, *elem);
1379 str_ncat(str," ",1);
1381 (void)astore(ary, ++sp, str = str_static(&str_no));
1382 str_numset(str, (double)pent->p_proto);
1386 (void)astore(ary, ++sp, str_static(&str_no));
1394 do_gsent(which,gimme,arglast)
1399 register ARRAY *ary = stack;
1400 register int sp = arglast[0];
1401 register char **elem;
1403 struct servent *getservbyname();
1404 struct servent *getservbynumber();
1405 struct servent *getservent();
1406 struct servent *sent;
1408 if (gimme != G_ARRAY) {
1409 astore(ary, ++sp, str_static(&str_undef));
1413 if (which == O_GSBYNAME) {
1414 char *name = str_get(ary->ary_array[sp+1]);
1415 char *proto = str_get(ary->ary_array[sp+2]);
1417 if (proto && !*proto)
1420 sent = getservbyname(name,proto);
1422 else if (which == O_GSBYPORT) {
1423 int port = (int)str_gnum(ary->ary_array[sp+1]);
1424 char *proto = str_get(ary->ary_array[sp+2]);
1426 sent = getservbyport(port,proto);
1429 sent = getservent();
1432 (void)astore(ary, ++sp, str = str_static(&str_no));
1433 str_set(str, sent->s_name);
1434 (void)astore(ary, ++sp, str = str_static(&str_no));
1435 for (elem = sent->s_aliases; *elem; elem++) {
1436 str_cat(str, *elem);
1438 str_ncat(str," ",1);
1440 (void)astore(ary, ++sp, str = str_static(&str_no));
1442 str_numset(str, (double)ntohs(sent->s_port));
1444 str_numset(str, (double)(sent->s_port));
1446 (void)astore(ary, ++sp, str = str_static(&str_no));
1447 str_set(str, sent->s_proto);
1451 (void)astore(ary, ++sp, str_static(&str_no));
1459 do_select(gimme,arglast)
1463 register STR **st = stack->ary_array;
1464 register int sp = arglast[0];
1472 struct timeval timebuf;
1473 struct timeval *tbuf = &timebuf;
1475 for (i = 1; i <= 3; i++) {
1476 j = st[sp+i]->str_len;
1480 for (i = 1; i <= 3; i++) {
1485 str_grow(str,maxlen);
1486 s = str_get(str) + j;
1487 while (++j <= maxlen) {
1491 else if (str->str_ptr) {
1492 Safefree(str->str_ptr);
1493 str->str_ptr = Nullch;
1498 if (str->str_nok || str->str_pok) {
1499 value = str_gnum(str);
1502 timebuf.tv_sec = (long)value;
1503 value -= (double)timebuf.tv_sec;
1504 timebuf.tv_usec = (long)(value * 1000000.0);
1507 tbuf = Null(struct timeval*);
1516 st[++sp] = str_static(&str_no);
1517 str_numset(st[sp], (double)nfound);
1518 if (gimme == G_ARRAY && tbuf) {
1519 value = (double)(timebuf.tv_sec) +
1520 (double)(timebuf.tv_usec) / 1000000.0;
1521 st[++sp] = str_static(&str_no);
1522 str_numset(st[sp], value);
1528 do_spair(stab1, stab2, arglast)
1533 register STR **st = stack->ary_array;
1534 register int sp = arglast[2];
1535 register STIO *stio1;
1536 register STIO *stio2;
1537 int domain, type, protocol, fd[2];
1539 if (!stab1 || !stab2)
1542 stio1 = stab_io(stab1);
1543 stio2 = stab_io(stab2);
1545 stio1 = stab_io(stab1) = stio_new();
1546 else if (stio1->ifp)
1547 do_close(stab1,FALSE);
1549 stio2 = stab_io(stab2) = stio_new();
1550 else if (stio2->ifp)
1551 do_close(stab2,FALSE);
1553 domain = (int)str_gnum(st[++sp]);
1554 type = (int)str_gnum(st[++sp]);
1555 protocol = (int)str_gnum(st[++sp]);
1557 taintproper("Insecure dependency in socketpair");
1560 if (socketpair(domain,type,protocol,fd) < 0)
1563 fatal("Socketpair unimplemented");
1565 stio1->ifp = fdopen(fd[0], "r");
1566 stio1->ofp = fdopen(fd[0], "w");
1568 stio2->ifp = fdopen(fd[1], "r");
1569 stio2->ofp = fdopen(fd[1], "w");
1578 do_gpwent(which,gimme,arglast)
1584 register ARRAY *ary = stack;
1585 register int sp = arglast[0];
1586 register char **elem;
1588 struct passwd *getpwnam();
1589 struct passwd *getpwuid();
1590 struct passwd *getpwent();
1591 struct passwd *pwent;
1594 if (gimme != G_ARRAY) {
1595 astore(ary, ++sp, str_static(&str_undef));
1599 if (which == O_GPWNAM) {
1600 char *name = str_get(ary->ary_array[sp+1]);
1602 pwent = getpwnam(name);
1604 else if (which == O_GPWUID) {
1605 int uid = (int)str_gnum(ary->ary_array[sp+1]);
1607 pwent = getpwuid(uid);
1613 (void)astore(ary, ++sp, str = str_static(&str_no));
1614 str_set(str, pwent->pw_name);
1615 (void)astore(ary, ++sp, str = str_static(&str_no));
1616 str_set(str, pwent->pw_passwd);
1617 (void)astore(ary, ++sp, str = str_static(&str_no));
1618 str_numset(str, (double)pwent->pw_uid);
1619 (void)astore(ary, ++sp, str = str_static(&str_no));
1620 str_numset(str, (double)pwent->pw_gid);
1621 (void)astore(ary, ++sp, str = str_static(&str_no));
1623 str_numset(str, (double)pwent->pw_change);
1626 str_numset(str, (double)pwent->pw_quota);
1629 str_set(str, pwent->pw_age);
1633 (void)astore(ary, ++sp, str = str_static(&str_no));
1635 str_set(str,pwent->pw_class);
1637 str_set(str, pwent->pw_comment);
1639 (void)astore(ary, ++sp, str = str_static(&str_no));
1640 str_set(str, pwent->pw_gecos);
1641 (void)astore(ary, ++sp, str = str_static(&str_no));
1642 str_set(str, pwent->pw_dir);
1643 (void)astore(ary, ++sp, str = str_static(&str_no));
1644 str_set(str, pwent->pw_shell);
1646 (void)astore(ary, ++sp, str = str_static(&str_no));
1647 str_numset(str, (double)pwent->pw_expire);
1653 fatal("password routines not implemented");
1658 do_ggrent(which,gimme,arglast)
1664 register ARRAY *ary = stack;
1665 register int sp = arglast[0];
1666 register char **elem;
1668 struct group *getgrnam();
1669 struct group *getgrgid();
1670 struct group *getgrent();
1671 struct group *grent;
1674 if (gimme != G_ARRAY) {
1675 astore(ary, ++sp, str_static(&str_undef));
1679 if (which == O_GGRNAM) {
1680 char *name = str_get(ary->ary_array[sp+1]);
1682 grent = getgrnam(name);
1684 else if (which == O_GGRGID) {
1685 int gid = (int)str_gnum(ary->ary_array[sp+1]);
1687 grent = getgrgid(gid);
1693 (void)astore(ary, ++sp, str = str_static(&str_no));
1694 str_set(str, grent->gr_name);
1695 (void)astore(ary, ++sp, str = str_static(&str_no));
1696 str_set(str, grent->gr_passwd);
1697 (void)astore(ary, ++sp, str = str_static(&str_no));
1698 str_numset(str, (double)grent->gr_gid);
1699 (void)astore(ary, ++sp, str = str_static(&str_no));
1700 for (elem = grent->gr_mem; *elem; elem++) {
1701 str_cat(str, *elem);
1703 str_ncat(str," ",1);
1709 fatal("group routines not implemented");
1714 do_dirop(optype,stab,gimme,arglast)
1721 register ARRAY *ary = stack;
1722 register STR **st = ary->ary_array;
1723 register int sp = arglast[1];
1724 register STIO *stio;
1729 struct DIRENT *readdir();
1730 register struct DIRENT *dp;
1734 if (!(stio = stab_io(stab)))
1735 stio = stab_io(stab) = stio_new();
1736 if (!stio->dirp && optype != O_OPENDIR)
1742 closedir(stio->dirp);
1743 if (!(stio->dirp = opendir(str_get(st[sp+1]))))
1747 if (gimme == G_ARRAY) {
1749 while (dp = readdir(stio->dirp)) {
1751 (void)astore(ary,++sp,
1752 str_2static(str_make(dp->d_name,dp->d_namlen)));
1754 (void)astore(ary,++sp,
1755 str_2static(str_make(dp->d_name,0)));
1760 if (!(dp = readdir(stio->dirp)))
1762 st[sp] = str_static(&str_undef);
1764 str_nset(st[sp], dp->d_name, dp->d_namlen);
1766 str_set(st[sp], dp->d_name);
1771 st[sp] = str_static(&str_undef);
1772 str_numset(st[sp], (double)telldir(stio->dirp));
1775 st[sp] = str_static(&str_undef);
1776 along = (long)str_gnum(st[sp+1]);
1777 (void)seekdir(stio->dirp,along);
1780 st[sp] = str_static(&str_undef);
1781 (void)rewinddir(stio->dirp);
1784 st[sp] = str_static(&str_undef);
1785 (void)closedir(stio->dirp);
1792 st[sp] = &str_undef;
1796 fatal("Unimplemented directory operation");
1804 register STR **st = stack->ary_array;
1805 register int sp = arglast[1];
1806 register int items = arglast[2] - sp;
1809 register int tot = 0;
1813 for (st += ++sp; items--; st++)
1814 tainted |= (*st)->str_tainted;
1815 st = stack->ary_array;
1817 items = arglast[2] - sp;
1822 taintproper("Insecure dependency in chmod");
1826 val = (int)str_gnum(st[++sp]);
1828 if (chmod(str_get(st[++sp]),val))
1835 taintproper("Insecure dependency in chown");
1840 val = (int)str_gnum(st[++sp]);
1841 val2 = (int)str_gnum(st[++sp]);
1843 if (chown(str_get(st[++sp]),val,val2))
1850 taintproper("Insecure dependency in kill");
1854 s = str_get(st[++sp]);
1856 if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1858 if (!(val = whichsig(s)))
1859 fatal("Unrecognized signal name \"%s\"",s);
1862 val = (int)str_gnum(st[sp]);
1866 int proc = (int)str_gnum(st[++sp]);
1868 if (killpg(proc,val)) /* BSD */
1870 if (kill(-proc,val)) /* SYSV */
1877 if (kill((int)(str_gnum(st[++sp])),val))
1885 taintproper("Insecure dependency in unlink");
1889 s = str_get(st[++sp]);
1890 if (euid || unsafe) {
1894 else { /* don't let root wipe out directories without -U */
1896 if (lstat(s,&statbuf) < 0 ||
1898 if (stat(s,&statbuf) < 0 ||
1900 (statbuf.st_mode & S_IFMT) == S_IFDIR )
1911 taintproper("Insecure dependency in utime");
1919 utbuf.atime = (long)str_gnum(st[++sp]); /* time accessed */
1920 utbuf.mtime = (long)str_gnum(st[++sp]); /* time modified */
1925 if (utime(str_get(st[++sp]),&utbuf))
1937 /* Do the permissions allow some operation? Assumes statcache already set. */
1940 cando(bit, effective, statbufp)
1943 register struct stat *statbufp;
1945 if ((effective ? euid : uid) == 0) { /* root is special */
1946 if (bit == S_IEXEC) {
1947 if (statbufp->st_mode & 0111 ||
1948 (statbufp->st_mode & S_IFMT) == S_IFDIR )
1952 return TRUE; /* root reads and writes anything */
1955 if (statbufp->st_uid == (effective ? euid : uid) ) {
1956 if (statbufp->st_mode & bit)
1957 return TRUE; /* ok as "user" */
1959 else if (ingroup((int)statbufp->st_gid,effective)) {
1960 if (statbufp->st_mode & bit >> 3)
1961 return TRUE; /* ok as "group" */
1963 else if (statbufp->st_mode & bit >> 6)
1964 return TRUE; /* ok as "other" */
1969 ingroup(testgid,effective)
1973 if (testgid == (effective ? egid : gid))
1980 GIDTYPE gary[NGROUPS];
1983 anum = getgroups(NGROUPS,gary);
1985 if (gary[anum] == testgid)