1 /* $Header: doio.c,v 3.0.1.6 90/03/12 16:30:07 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.6 90/03/12 16:30:07 lwall
10 * patch13: system 'FOO=bar command' didn't invoke sh as it should
12 * Revision 3.0.1.5 90/02/28 17:01:36 lwall
13 * patch9: open(FOO,"$filename\0") will now protect trailing spaces in filename
14 * patch9: removed obsolete checks to avoid opening block devices
15 * patch9: removed references to acusec and modusec that some utime.h's have
16 * patch9: added pipe function
18 * Revision 3.0.1.4 89/12/21 19:55:10 lwall
19 * patch7: select now works on big-endian machines
20 * patch7: errno may now be a macro with an lvalue
21 * patch7: ANSI strerror() is now supported
22 * patch7: Configure now detects DG/UX thingies like [sg]etpgrp2 and utime.h
24 * Revision 3.0.1.3 89/11/17 15:13:06 lwall
25 * patch5: some systems have symlink() but not lstat()
26 * patch5: some systems have dirent.h but not readdir()
28 * Revision 3.0.1.2 89/11/11 04:25:51 lwall
29 * patch2: orthogonalized the file modes some so we can have <& +<& etc.
30 * patch2: do_open() now detects sockets passed to process from parent
31 * patch2: fd's above 2 are now closed on exec
32 * patch2: csh code can now use csh from other than /bin
33 * patch2: getsockopt, get{sock,peer}name didn't define result properly
34 * patch2: warn("shutdown") was replicated
35 * patch2: gethostbyname was misdeclared
36 * patch2: telldir() is sometimes a macro
38 * Revision 3.0.1.1 89/10/26 23:10:05 lwall
39 * patch1: Configure now checks for BSD shadow passwords
41 * Revision 3.0 89/10/18 15:10:54 lwall
50 #include <sys/socket.h>
65 do_open(stab,name,len)
71 register STIO *stio = stab_io(stab);
72 char *myname = savestr(name);
76 char mode[3]; /* stdio file mode ("r\0" or "r+\0") */
79 forkprocess = 1; /* assume true if no fork */
80 while (len && isspace(name[len-1]))
83 stio = stab_io(stab) = stio_new();
85 fd = fileno(stio->ifp);
86 if (stio->type == '|')
87 result = mypclose(stio->ifp);
88 else if (stio->ifp != stio->ofp) {
91 result = fclose(stio->ifp);
93 else if (stio->type != '-')
94 result = fclose(stio->ifp);
97 if (result == EOF && fd > 2)
98 fprintf(stderr,"Warning: unable to close filehandle %s properly.\n",
100 stio->ofp = stio->ifp = Nullfp;
102 if (*name == '+' && len > 1 && name[len-1] != '|') { /* scary */
113 for (name++; isspace(*name); name++) ;
116 taintproper("Insecure dependency in piped open");
118 fp = mypopen(name,"w");
121 else if (*name == '>') {
123 taintproper("Insecure dependency in open");
127 mode[0] = stio->type = 'a';
136 while (isspace(*name))
141 stab = stabent(name,FALSE);
142 if (!stab || !stab_io(stab))
144 if (stab_io(stab) && stab_io(stab)->ifp) {
145 fd = fileno(stab_io(stab)->ifp);
146 if (stab_io(stab)->type == 's')
152 fp = fdopen(dup(fd),mode);
155 while (isspace(*name))
157 if (strEQ(name,"-")) {
162 fp = fopen(name,mode);
170 while (isspace(*name))
174 if (strEQ(name,"-")) {
179 fp = fopen(name,mode);
181 else if (name[len-1] == '|') {
184 taintproper("Insecure dependency in piped open");
187 while (len && isspace(name[len-1]))
189 for (; isspace(*name); name++) ;
190 fp = mypopen(name,"r");
195 for (; isspace(*name); name++) ;
196 if (strEQ(name,"-")) {
201 fp = fopen(name,"r");
208 stio->type != '|' && stio->type != '-') {
209 if (fstat(fileno(fp),&statbuf) < 0) {
213 result = (statbuf.st_mode & S_IFMT);
215 if (result == S_IFSOCK || result == 0)
216 stio->type = 's'; /* in case a socket was passed in to us */
219 #if defined(FCNTL) && defined(F_SETFD)
226 if (stio->type != 's')
229 stio->ofp = fdopen(fileno(fp),"w");
240 int filemode,fileuid,filegid;
242 while (alen(stab_xarray(stab)) >= 0) {
243 str = ashift(stab_xarray(stab));
244 str_sset(stab_val(stab),str);
245 STABSET(stab_val(stab));
246 oldname = str_get(stab_val(stab));
247 if (do_open(stab,oldname,stab_val(stab)->str_cur)) {
250 taintproper("Insecure dependency in inplace open");
252 filemode = statbuf.st_mode;
253 fileuid = statbuf.st_uid;
254 filegid = statbuf.st_gid;
256 str_cat(str,inplace);
258 (void)rename(oldname,str->str_ptr);
260 (void)UNLINK(str->str_ptr);
261 (void)link(oldname,str->str_ptr);
262 (void)UNLINK(oldname);
266 (void)UNLINK(oldname);
270 str_cat(str,oldname);
271 errno = 0; /* in case sprintf set errno */
272 if (!do_open(argvoutstab,str->str_ptr,str->str_cur))
273 fatal("Can't do inplace edit");
274 defoutstab = argvoutstab;
276 (void)fchmod(fileno(stab_io(argvoutstab)->ifp),filemode);
278 (void)chmod(oldname,filemode);
281 (void)fchown(fileno(stab_io(argvoutstab)->ifp),fileuid,filegid);
283 (void)chown(oldname,fileuid,filegid);
287 return stab_io(stab)->ifp;
290 fprintf(stderr,"Can't open %s\n",str_get(str));
294 (void)do_close(argvoutstab,FALSE);
295 defoutstab = stabent("STDOUT",TRUE);
301 do_pipe(str, rstab, wstab)
306 register STIO *rstio;
307 register STIO *wstio;
315 rstio = stab_io(rstab);
316 wstio = stab_io(wstab);
319 rstio = stab_io(rstab) = stio_new();
321 do_close(rstab,FALSE);
323 wstio = stab_io(wstab) = stio_new();
325 do_close(wstab,FALSE);
329 rstio->ifp = fdopen(fd[0], "r");
330 wstio->ofp = fdopen(fd[1], "w");
331 wstio->ifp = wstio->ofp;
335 str_sset(str,&str_yes);
339 str_sset(str,&str_undef);
344 do_close(stab,explicit)
349 register STIO *stio = stab_io(stab);
352 if (!stio) { /* never opened */
353 if (dowarn && explicit)
354 warn("Close on unopened file <%s>",stab_name(stab));
358 if (stio->type == '|') {
359 status = mypclose(stio->ifp);
360 retval = (status >= 0);
361 statusvalue = (unsigned)status & 0xffff;
363 else if (stio->type == '-')
366 if (stio->ofp && stio->ofp != stio->ifp) /* a socket */
368 retval = (fclose(stio->ifp) != EOF);
370 stio->ofp = stio->ifp = Nullfp;
385 if (!stab) { /* eof() */
387 stio = stab_io(argvstab);
392 stio = stab_io(stab);
399 #ifdef STDSTDIO /* (the code works without this) */
400 if (stio->ifp->_cnt > 0) /* cheat a little, since */
401 return FALSE; /* this is the most usual case */
404 ch = getc(stio->ifp);
406 (void)ungetc(ch, stio->ifp);
409 if (!stab) { /* not necessarily a real EOF yet? */
410 if (!nextargv(argvstab)) /* get another fp handy */
414 return TRUE; /* normal fp, definitely end of file */
428 stio = stab_io(stab);
429 if (!stio || !stio->ifp)
433 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
435 return ftell(stio->ifp);
439 warn("tell() on unopened file");
444 do_seek(stab, pos, whence)
454 stio = stab_io(stab);
455 if (!stio || !stio->ifp)
459 (void)fseek (stio->ifp, 0L, 2); /* ultrix 1.2 workaround */
461 return fseek(stio->ifp, pos, whence) >= 0;
465 warn("seek() on unopened file");
470 do_ctl(optype,stab,func,argstr)
480 if (!stab || !argstr)
482 stio = stab_io(stab);
486 if (argstr->str_pok || !argstr->str_nok) {
487 if (!argstr->str_pok)
492 #define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK)
496 retval = IOCPARM_LEN(func); /* on BSDish systes we're safe */
498 retval = 256; /* otherwise guess at what's safe */
500 if (argstr->str_cur < retval) {
501 str_grow(argstr,retval+1);
502 argstr->str_cur = retval;
506 s[argstr->str_cur] = 17; /* a little sanity check here */
509 retval = (int)str_gnum(argstr);
510 s = (char*)retval; /* ouch */
514 if (optype == O_IOCTL)
515 retval = ioctl(fileno(stio->ifp), func, s);
518 retval = fcntl(fileno(stio->ifp), func, s);
520 fatal("fcntl is not implemented");
526 if (argstr->str_pok) {
527 if (s[argstr->str_cur] != 17)
528 fatal("Return value overflowed string");
529 s[argstr->str_cur] = 0; /* put our null back */
535 do_stat(str,arg,gimme,arglast)
541 register ARRAY *ary = stack;
542 register int sp = arglast[0] + 1;
546 if ((arg[1].arg_type & A_MASK) == A_WORD) {
547 tmpstab = arg[1].arg_ptr.arg_stab;
548 if (tmpstab != defstab) {
550 str_set(statname,"");
551 if (!stab_io(tmpstab) ||
552 fstat(fileno(stab_io(tmpstab)->ifp),&statcache) < 0) {
558 str_sset(statname,ary->ary_array[sp]);
561 if (arg->arg_type == O_LSTAT)
562 i = lstat(str_get(statname),&statcache);
565 i = stat(str_get(statname),&statcache);
570 if (gimme != G_ARRAY) {
572 str_sset(str,&str_yes);
574 str_sset(str,&str_undef);
576 ary->ary_array[sp] = str;
582 (void)astore(ary,++sp,
583 str_2static(str_nmake((double)statcache.st_dev)));
584 (void)astore(ary,++sp,
585 str_2static(str_nmake((double)statcache.st_ino)));
586 (void)astore(ary,++sp,
587 str_2static(str_nmake((double)statcache.st_mode)));
588 (void)astore(ary,++sp,
589 str_2static(str_nmake((double)statcache.st_nlink)));
590 (void)astore(ary,++sp,
591 str_2static(str_nmake((double)statcache.st_uid)));
592 (void)astore(ary,++sp,
593 str_2static(str_nmake((double)statcache.st_gid)));
594 (void)astore(ary,++sp,
595 str_2static(str_nmake((double)statcache.st_rdev)));
596 (void)astore(ary,++sp,
597 str_2static(str_nmake((double)statcache.st_size)));
598 (void)astore(ary,++sp,
599 str_2static(str_nmake((double)statcache.st_atime)));
600 (void)astore(ary,++sp,
601 str_2static(str_nmake((double)statcache.st_mtime)));
602 (void)astore(ary,++sp,
603 str_2static(str_nmake((double)statcache.st_ctime)));
605 (void)astore(ary,++sp,
606 str_2static(str_nmake((double)statcache.st_blksize)));
607 (void)astore(ary,++sp,
608 str_2static(str_nmake((double)statcache.st_blocks)));
610 (void)astore(ary,++sp,
611 str_2static(str_make("",0)));
612 (void)astore(ary,++sp,
613 str_2static(str_make("",0)));
616 (void)astore(ary,++sp,str_nmake(0.0));
623 looks_like_number(str)
632 send = s + str->str_cur;
637 if (*s == '+' || *s == '-')
645 else if (s == str->str_ptr)
651 if (*s == 'e' || *s == 'E') {
653 if (*s == '+' || *s == '-')
674 warn("print to unopened file");
680 ((str->str_nok && str->str_u.str_nval != 0.0)
681 || (looks_like_number(str) && str_gnum(str) != 0.0) ) )
682 fprintf(fp, ofmt, str->str_u.str_nval);
685 if (*tmps == 'S' && tmps[1] == 't' && tmps[2] == 'a' && tmps[3] == 'b'
686 && str->str_cur == sizeof(STBP) && strlen(tmps) < str->str_cur) {
687 tmps = stab_name(((STAB*)str)); /* a stab value, be nice */
688 str = ((STAB*)str)->str_magic;
691 if (str->str_cur && fwrite(tmps,1,str->str_cur,fp) == 0)
698 do_aprint(arg,fp,arglast)
703 register STR **st = stack->ary_array;
704 register int sp = arglast[1];
706 register int items = arglast[2] - sp;
710 warn("print to unopened file");
714 if (arg->arg_type == O_PRTF) {
715 do_sprintf(arg->arg_ptr.arg_str,items,st);
716 retval = do_print(arg->arg_ptr.arg_str,fp);
719 retval = (items <= 0);
720 for (; items > 0; items--,st++) {
721 if (retval && ofslen) {
722 if (fwrite(ofs, 1, ofslen, fp) == 0) {
727 if (!(retval = do_print(*st, fp)))
730 if (retval && orslen)
731 if (fwrite(ors, 1, orslen, fp) == 0)
744 if (arg[1].arg_type & A_DONT) {
745 stio = stab_io(arg[1].arg_ptr.arg_stab);
746 if (stio && stio->ifp) {
747 statstab = arg[1].arg_ptr.arg_stab;
748 str_set(statname,"");
749 return fstat(fileno(stio->ifp), &statcache);
752 if (arg[1].arg_ptr.arg_stab == defstab)
755 warn("Stat on unopened file <%s>",
756 stab_name(arg[1].arg_ptr.arg_stab));
758 str_set(statname,"");
764 str_sset(statname,str);
765 return stat(str_get(str),&statcache);
781 if (arg[1].arg_type & A_DONT) {
782 if (arg[1].arg_ptr.arg_stab == defstab) {
784 stio = stab_io(statstab);
787 goto really_filename;
791 statstab = arg[1].arg_ptr.arg_stab;
792 str_set(statname,"");
793 stio = stab_io(statstab);
795 if (stio && stio->ifp) {
797 fstat(fileno(stio->ifp),&statcache);
798 if (stio->ifp->_cnt <= 0) {
801 (void)ungetc(i,stio->ifp);
803 if (stio->ifp->_cnt <= 0) /* null file is anything */
805 len = stio->ifp->_cnt + (stio->ifp->_ptr - stio->ifp->_base);
806 s = stio->ifp->_base;
808 fatal("-T and -B not implemented on filehandles\n");
813 warn("Test on unopened file <%s>",
814 stab_name(arg[1].arg_ptr.arg_stab));
820 str_sset(statname,str);
822 i = open(str_get(str),0);
826 len = read(i,tbuf,512);
827 if (len <= 0) /* null file is anything */
833 /* now scan s to look for textiness */
835 for (i = 0; i < len; i++,s++) {
836 if (!*s) { /* null never allowed in text */
843 *s != '\n' && *s != '\r' && *s != '\b' &&
844 *s != '\t' && *s != '\f' && *s != 27)
848 if ((odd * 10 > len) == (arg->arg_type == O_FTTEXT)) /* allow 10% odd */
855 do_aexec(really,arglast)
859 register STR **st = stack->ary_array;
860 register int sp = arglast[1];
861 register int items = arglast[2] - sp;
867 New(401,argv, items+1, char*);
869 for (st += ++sp; items > 0; items--,st++) {
877 if (*argv[0] != '/') /* will execvp use PATH? */
878 taintenv(); /* testing IFS here is overkill, probably */
880 if (really && *(tmps = str_get(really)))
883 execvp(argv[0],argv);
900 taintproper("Insecure dependency in exec");
903 /* save an extra exec if possible */
906 if (strnEQ(cmd,cshname,cshlen) && strnEQ(cmd+cshlen," -c",3)) {
924 execl(cshname,"csh", flags,ncmd,(char*)0);
932 /* see if there are shell metacharacters in it */
934 for (s = cmd; *s; s++) {
935 if (*s != ' ' && !isalpha(*s) && index("$&*(){}[]'\";\\|?<>~`\n",*s)) {
936 if (*s == '\n' && !s[1]) {
941 execl("/bin/sh","sh","-c",cmd,(char*)0);
945 for (s = cmd; *s && isalpha(*s); s++) ; /* catch VAR=val gizmo */
948 New(402,argv, (s - cmd) / 2 + 2, char*);
952 while (*s && isspace(*s)) s++;
955 while (*s && !isspace(*s)) s++;
961 execvp(argv[0],argv);
962 if (errno == ENOEXEC) /* for system V NIH syndrome */
971 do_socket(stab, arglast)
975 register STR **st = stack->ary_array;
976 register int sp = arglast[1];
978 int domain, type, protocol, fd;
983 stio = stab_io(stab);
985 stio = stab_io(stab) = stio_new();
987 do_close(stab,FALSE);
989 domain = (int)str_gnum(st[++sp]);
990 type = (int)str_gnum(st[++sp]);
991 protocol = (int)str_gnum(st[++sp]);
993 taintproper("Insecure dependency in socket");
995 fd = socket(domain,type,protocol);
998 stio->ifp = fdopen(fd, "r"); /* stdio gets confused about sockets */
999 stio->ofp = fdopen(fd, "w");
1006 do_bind(stab, arglast)
1010 register STR **st = stack->ary_array;
1011 register int sp = arglast[1];
1012 register STIO *stio;
1018 stio = stab_io(stab);
1019 if (!stio || !stio->ifp)
1022 addr = str_get(st[++sp]);
1024 taintproper("Insecure dependency in bind");
1026 return bind(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
1030 warn("bind() on closed fd");
1036 do_connect(stab, arglast)
1040 register STR **st = stack->ary_array;
1041 register int sp = arglast[1];
1042 register STIO *stio;
1048 stio = stab_io(stab);
1049 if (!stio || !stio->ifp)
1052 addr = str_get(st[++sp]);
1054 taintproper("Insecure dependency in connect");
1056 return connect(fileno(stio->ifp), addr, st[sp]->str_cur) >= 0;
1060 warn("connect() on closed fd");
1066 do_listen(stab, arglast)
1070 register STR **st = stack->ary_array;
1071 register int sp = arglast[1];
1072 register STIO *stio;
1078 stio = stab_io(stab);
1079 if (!stio || !stio->ifp)
1082 backlog = (int)str_gnum(st[++sp]);
1083 return listen(fileno(stio->ifp), backlog) >= 0;
1087 warn("listen() on closed fd");
1092 do_accept(str, nstab, gstab)
1097 register STIO *nstio;
1098 register STIO *gstio;
1099 int len = sizeof buf;
1107 gstio = stab_io(gstab);
1108 nstio = stab_io(nstab);
1110 if (!gstio || !gstio->ifp)
1113 nstio = stab_io(nstab) = stio_new();
1114 else if (nstio->ifp)
1115 do_close(nstab,FALSE);
1117 fd = accept(fileno(gstio->ifp),buf,&len);
1120 nstio->ifp = fdopen(fd, "r");
1121 nstio->ofp = fdopen(fd, "w");
1124 str_nset(str, buf, len);
1129 warn("accept() on closed fd");
1131 str_sset(str,&str_undef);
1136 do_shutdown(stab, arglast)
1140 register STR **st = stack->ary_array;
1141 register int sp = arglast[1];
1142 register STIO *stio;
1148 stio = stab_io(stab);
1149 if (!stio || !stio->ifp)
1152 how = (int)str_gnum(st[++sp]);
1153 return shutdown(fileno(stio->ifp), how) >= 0;
1157 warn("shutdown() on closed fd");
1163 do_sopt(optype, stab, arglast)
1168 register STR **st = stack->ary_array;
1169 register int sp = arglast[1];
1170 register STIO *stio;
1178 stio = stab_io(stab);
1179 if (!stio || !stio->ifp)
1182 fd = fileno(stio->ifp);
1183 lvl = (int)str_gnum(st[sp+1]);
1184 optname = (int)str_gnum(st[sp+2]);
1187 st[sp] = str_2static(str_new(257));
1188 st[sp]->str_cur = 256;
1189 st[sp]->str_pok = 1;
1190 if (getsockopt(fd, lvl, optname, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1195 if (setsockopt(fd, lvl, optname, st[sp]->str_ptr, st[sp]->str_cur) < 0)
1205 warn("[gs]etsockopt() on closed fd");
1206 st[sp] = &str_undef;
1212 do_getsockname(optype, stab, arglast)
1217 register STR **st = stack->ary_array;
1218 register int sp = arglast[1];
1219 register STIO *stio;
1225 stio = stab_io(stab);
1226 if (!stio || !stio->ifp)
1229 st[sp] = str_2static(str_new(257));
1230 st[sp]->str_cur = 256;
1231 st[sp]->str_pok = 1;
1232 fd = fileno(stio->ifp);
1235 if (getsockname(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1239 if (getpeername(fd, st[sp]->str_ptr, &st[sp]->str_cur) < 0)
1248 warn("get{sock,peer}name() on closed fd");
1249 st[sp] = &str_undef;
1255 do_ghent(which,gimme,arglast)
1260 register ARRAY *ary = stack;
1261 register int sp = arglast[0];
1262 register char **elem;
1264 struct hostent *gethostbyname();
1265 struct hostent *gethostbyaddr();
1267 struct hostent *gethostent();
1269 struct hostent *hent;
1272 if (gimme != G_ARRAY) {
1273 astore(ary, ++sp, str_static(&str_undef));
1277 if (which == O_GHBYNAME) {
1278 char *name = str_get(ary->ary_array[sp+1]);
1280 hent = gethostbyname(name);
1282 else if (which == O_GHBYADDR) {
1283 STR *addrstr = ary->ary_array[sp+1];
1284 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1285 char *addr = str_get(addrstr);
1287 hent = gethostbyaddr(addr,addrstr->str_cur,addrtype);
1291 hent = gethostent();
1293 fatal("gethostent not implemented");
1297 (void)astore(ary, ++sp, str = str_static(&str_no));
1298 str_set(str, hent->h_name);
1299 (void)astore(ary, ++sp, str = str_static(&str_no));
1300 for (elem = hent->h_aliases; *elem; elem++) {
1301 str_cat(str, *elem);
1303 str_ncat(str," ",1);
1305 (void)astore(ary, ++sp, str = str_static(&str_no));
1306 str_numset(str, (double)hent->h_addrtype);
1307 (void)astore(ary, ++sp, str = str_static(&str_no));
1308 len = hent->h_length;
1309 str_numset(str, (double)len);
1311 for (elem = hent->h_addr_list; *elem; elem++) {
1312 (void)astore(ary, ++sp, str = str_static(&str_no));
1313 str_nset(str, *elem, len);
1316 (void)astore(ary, ++sp, str = str_static(&str_no));
1317 str_nset(str, hent->h_addr, len);
1322 (void)astore(ary, ++sp, str_static(&str_no));
1330 do_gnent(which,gimme,arglast)
1335 register ARRAY *ary = stack;
1336 register int sp = arglast[0];
1337 register char **elem;
1339 struct netent *getnetbyname();
1340 struct netent *getnetbyaddr();
1341 struct netent *getnetent();
1342 struct netent *nent;
1344 if (gimme != G_ARRAY) {
1345 astore(ary, ++sp, str_static(&str_undef));
1349 if (which == O_GNBYNAME) {
1350 char *name = str_get(ary->ary_array[sp+1]);
1352 nent = getnetbyname(name);
1354 else if (which == O_GNBYADDR) {
1355 STR *addrstr = ary->ary_array[sp+1];
1356 int addrtype = (int)str_gnum(ary->ary_array[sp+2]);
1357 char *addr = str_get(addrstr);
1359 nent = getnetbyaddr(addr,addrtype);
1366 (void)astore(ary, ++sp, str = str_static(&str_no));
1367 str_set(str, nent->n_name);
1368 (void)astore(ary, ++sp, str = str_static(&str_no));
1369 for (elem = nent->n_aliases; *elem; elem++) {
1370 str_cat(str, *elem);
1372 str_ncat(str," ",1);
1374 (void)astore(ary, ++sp, str = str_static(&str_no));
1375 str_numset(str, (double)nent->n_addrtype);
1376 (void)astore(ary, ++sp, str = str_static(&str_no));
1377 str_numset(str, (double)nent->n_net);
1381 (void)astore(ary, ++sp, str_static(&str_no));
1389 do_gpent(which,gimme,arglast)
1394 register ARRAY *ary = stack;
1395 register int sp = arglast[0];
1396 register char **elem;
1398 struct protoent *getprotobyname();
1399 struct protoent *getprotobynumber();
1400 struct protoent *getprotoent();
1401 struct protoent *pent;
1403 if (gimme != G_ARRAY) {
1404 astore(ary, ++sp, str_static(&str_undef));
1408 if (which == O_GPBYNAME) {
1409 char *name = str_get(ary->ary_array[sp+1]);
1411 pent = getprotobyname(name);
1413 else if (which == O_GPBYNUMBER) {
1414 int proto = (int)str_gnum(ary->ary_array[sp+1]);
1416 pent = getprotobynumber(proto);
1419 pent = getprotoent();
1423 (void)astore(ary, ++sp, str = str_static(&str_no));
1424 str_set(str, pent->p_name);
1425 (void)astore(ary, ++sp, str = str_static(&str_no));
1426 for (elem = pent->p_aliases; *elem; elem++) {
1427 str_cat(str, *elem);
1429 str_ncat(str," ",1);
1431 (void)astore(ary, ++sp, str = str_static(&str_no));
1432 str_numset(str, (double)pent->p_proto);
1436 (void)astore(ary, ++sp, str_static(&str_no));
1444 do_gsent(which,gimme,arglast)
1449 register ARRAY *ary = stack;
1450 register int sp = arglast[0];
1451 register char **elem;
1453 struct servent *getservbyname();
1454 struct servent *getservbynumber();
1455 struct servent *getservent();
1456 struct servent *sent;
1458 if (gimme != G_ARRAY) {
1459 astore(ary, ++sp, str_static(&str_undef));
1463 if (which == O_GSBYNAME) {
1464 char *name = str_get(ary->ary_array[sp+1]);
1465 char *proto = str_get(ary->ary_array[sp+2]);
1467 if (proto && !*proto)
1470 sent = getservbyname(name,proto);
1472 else if (which == O_GSBYPORT) {
1473 int port = (int)str_gnum(ary->ary_array[sp+1]);
1474 char *proto = str_get(ary->ary_array[sp+2]);
1476 sent = getservbyport(port,proto);
1479 sent = getservent();
1482 (void)astore(ary, ++sp, str = str_static(&str_no));
1483 str_set(str, sent->s_name);
1484 (void)astore(ary, ++sp, str = str_static(&str_no));
1485 for (elem = sent->s_aliases; *elem; elem++) {
1486 str_cat(str, *elem);
1488 str_ncat(str," ",1);
1490 (void)astore(ary, ++sp, str = str_static(&str_no));
1492 str_numset(str, (double)ntohs(sent->s_port));
1494 str_numset(str, (double)(sent->s_port));
1496 (void)astore(ary, ++sp, str = str_static(&str_no));
1497 str_set(str, sent->s_proto);
1501 (void)astore(ary, ++sp, str_static(&str_no));
1509 do_select(gimme,arglast)
1513 register STR **st = stack->ary_array;
1514 register int sp = arglast[0];
1522 struct timeval timebuf;
1523 struct timeval *tbuf = &timebuf;
1525 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1531 #if BYTEORDER & 0xf0000
1532 #define ORDERBYTE (0x88888888 - BYTEORDER)
1534 #define ORDERBYTE (0x4444 - BYTEORDER)
1539 for (i = 1; i <= 3; i++) {
1540 j = st[sp+i]->str_cur;
1545 #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678
1546 growsize = maxlen; /* little endians can use vecs directly */
1554 masksize = NFDBITS / NBBY;
1556 masksize = sizeof(long); /* documented int, everyone seems to use long */
1558 growsize = maxlen + (masksize - (maxlen % masksize));
1559 Zero(&fd_sets[0], 4, char*);
1562 for (i = 1; i <= 3; i++) {
1567 str_grow(str,growsize);
1568 s = str_get(str) + j;
1569 while (++j <= growsize) {
1573 else if (str->str_ptr) {
1574 Safefree(str->str_ptr);
1575 str->str_ptr = Nullch;
1578 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1581 New(403, fd_sets[i], growsize, char);
1582 for (offset = 0; offset < growsize; offset += masksize) {
1583 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1584 fd_sets[i][j+offset] = s[(k % masksize) + offset];
1590 if (str->str_nok || str->str_pok) {
1591 value = str_gnum(str);
1594 timebuf.tv_sec = (long)value;
1595 value -= (double)timebuf.tv_sec;
1596 timebuf.tv_usec = (long)(value * 1000000.0);
1599 tbuf = Null(struct timeval*);
1601 #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678
1615 for (i = 1; i <= 3; i++) {
1619 for (offset = 0; offset < growsize; offset += masksize) {
1620 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1621 s[(k % masksize) + offset] = fd_sets[i][j+offset];
1627 st[++sp] = str_static(&str_no);
1628 str_numset(st[sp], (double)nfound);
1629 if (gimme == G_ARRAY && tbuf) {
1630 value = (double)(timebuf.tv_sec) +
1631 (double)(timebuf.tv_usec) / 1000000.0;
1632 st[++sp] = str_static(&str_no);
1633 str_numset(st[sp], value);
1639 do_spair(stab1, stab2, arglast)
1644 register STR **st = stack->ary_array;
1645 register int sp = arglast[2];
1646 register STIO *stio1;
1647 register STIO *stio2;
1648 int domain, type, protocol, fd[2];
1650 if (!stab1 || !stab2)
1653 stio1 = stab_io(stab1);
1654 stio2 = stab_io(stab2);
1656 stio1 = stab_io(stab1) = stio_new();
1657 else if (stio1->ifp)
1658 do_close(stab1,FALSE);
1660 stio2 = stab_io(stab2) = stio_new();
1661 else if (stio2->ifp)
1662 do_close(stab2,FALSE);
1664 domain = (int)str_gnum(st[++sp]);
1665 type = (int)str_gnum(st[++sp]);
1666 protocol = (int)str_gnum(st[++sp]);
1668 taintproper("Insecure dependency in socketpair");
1671 if (socketpair(domain,type,protocol,fd) < 0)
1674 fatal("Socketpair unimplemented");
1676 stio1->ifp = fdopen(fd[0], "r");
1677 stio1->ofp = fdopen(fd[0], "w");
1679 stio2->ifp = fdopen(fd[1], "r");
1680 stio2->ofp = fdopen(fd[1], "w");
1689 do_gpwent(which,gimme,arglast)
1695 register ARRAY *ary = stack;
1696 register int sp = arglast[0];
1697 register char **elem;
1699 struct passwd *getpwnam();
1700 struct passwd *getpwuid();
1701 struct passwd *getpwent();
1702 struct passwd *pwent;
1705 if (gimme != G_ARRAY) {
1706 astore(ary, ++sp, str_static(&str_undef));
1710 if (which == O_GPWNAM) {
1711 char *name = str_get(ary->ary_array[sp+1]);
1713 pwent = getpwnam(name);
1715 else if (which == O_GPWUID) {
1716 int uid = (int)str_gnum(ary->ary_array[sp+1]);
1718 pwent = getpwuid(uid);
1724 (void)astore(ary, ++sp, str = str_static(&str_no));
1725 str_set(str, pwent->pw_name);
1726 (void)astore(ary, ++sp, str = str_static(&str_no));
1727 str_set(str, pwent->pw_passwd);
1728 (void)astore(ary, ++sp, str = str_static(&str_no));
1729 str_numset(str, (double)pwent->pw_uid);
1730 (void)astore(ary, ++sp, str = str_static(&str_no));
1731 str_numset(str, (double)pwent->pw_gid);
1732 (void)astore(ary, ++sp, str = str_static(&str_no));
1734 str_numset(str, (double)pwent->pw_change);
1737 str_numset(str, (double)pwent->pw_quota);
1740 str_set(str, pwent->pw_age);
1744 (void)astore(ary, ++sp, str = str_static(&str_no));
1746 str_set(str,pwent->pw_class);
1748 str_set(str, pwent->pw_comment);
1750 (void)astore(ary, ++sp, str = str_static(&str_no));
1751 str_set(str, pwent->pw_gecos);
1752 (void)astore(ary, ++sp, str = str_static(&str_no));
1753 str_set(str, pwent->pw_dir);
1754 (void)astore(ary, ++sp, str = str_static(&str_no));
1755 str_set(str, pwent->pw_shell);
1757 (void)astore(ary, ++sp, str = str_static(&str_no));
1758 str_numset(str, (double)pwent->pw_expire);
1764 fatal("password routines not implemented");
1769 do_ggrent(which,gimme,arglast)
1775 register ARRAY *ary = stack;
1776 register int sp = arglast[0];
1777 register char **elem;
1779 struct group *getgrnam();
1780 struct group *getgrgid();
1781 struct group *getgrent();
1782 struct group *grent;
1785 if (gimme != G_ARRAY) {
1786 astore(ary, ++sp, str_static(&str_undef));
1790 if (which == O_GGRNAM) {
1791 char *name = str_get(ary->ary_array[sp+1]);
1793 grent = getgrnam(name);
1795 else if (which == O_GGRGID) {
1796 int gid = (int)str_gnum(ary->ary_array[sp+1]);
1798 grent = getgrgid(gid);
1804 (void)astore(ary, ++sp, str = str_static(&str_no));
1805 str_set(str, grent->gr_name);
1806 (void)astore(ary, ++sp, str = str_static(&str_no));
1807 str_set(str, grent->gr_passwd);
1808 (void)astore(ary, ++sp, str = str_static(&str_no));
1809 str_numset(str, (double)grent->gr_gid);
1810 (void)astore(ary, ++sp, str = str_static(&str_no));
1811 for (elem = grent->gr_mem; *elem; elem++) {
1812 str_cat(str, *elem);
1814 str_ncat(str," ",1);
1820 fatal("group routines not implemented");
1825 do_dirop(optype,stab,gimme,arglast)
1831 #if defined(DIRENT) && defined(READDIR)
1832 register ARRAY *ary = stack;
1833 register STR **st = ary->ary_array;
1834 register int sp = arglast[1];
1835 register STIO *stio;
1840 struct DIRENT *readdir();
1841 register struct DIRENT *dp;
1845 if (!(stio = stab_io(stab)))
1846 stio = stab_io(stab) = stio_new();
1847 if (!stio->dirp && optype != O_OPENDIR)
1853 closedir(stio->dirp);
1854 if (!(stio->dirp = opendir(str_get(st[sp+1]))))
1858 if (gimme == G_ARRAY) {
1860 while (dp = readdir(stio->dirp)) {
1862 (void)astore(ary,++sp,
1863 str_2static(str_make(dp->d_name,dp->d_namlen)));
1865 (void)astore(ary,++sp,
1866 str_2static(str_make(dp->d_name,0)));
1871 if (!(dp = readdir(stio->dirp)))
1873 st[sp] = str_static(&str_undef);
1875 str_nset(st[sp], dp->d_name, dp->d_namlen);
1877 str_set(st[sp], dp->d_name);
1882 st[sp] = str_static(&str_undef);
1883 str_numset(st[sp], (double)telldir(stio->dirp));
1886 st[sp] = str_static(&str_undef);
1887 along = (long)str_gnum(st[sp+1]);
1888 (void)seekdir(stio->dirp,along);
1891 st[sp] = str_static(&str_undef);
1892 (void)rewinddir(stio->dirp);
1895 st[sp] = str_static(&str_undef);
1896 (void)closedir(stio->dirp);
1903 st[sp] = &str_undef;
1907 fatal("Unimplemented directory operation");
1915 register STR **st = stack->ary_array;
1916 register int sp = arglast[1];
1917 register int items = arglast[2] - sp;
1920 register int tot = 0;
1924 for (st += ++sp; items--; st++)
1925 tainted |= (*st)->str_tainted;
1926 st = stack->ary_array;
1928 items = arglast[2] - sp;
1933 taintproper("Insecure dependency in chmod");
1937 val = (int)str_gnum(st[++sp]);
1939 if (chmod(str_get(st[++sp]),val))
1946 taintproper("Insecure dependency in chown");
1951 val = (int)str_gnum(st[++sp]);
1952 val2 = (int)str_gnum(st[++sp]);
1954 if (chown(str_get(st[++sp]),val,val2))
1961 taintproper("Insecure dependency in kill");
1965 s = str_get(st[++sp]);
1967 if (*s == 'S' && s[1] == 'I' && s[2] == 'G')
1969 if (!(val = whichsig(s)))
1970 fatal("Unrecognized signal name \"%s\"",s);
1973 val = (int)str_gnum(st[sp]);
1977 int proc = (int)str_gnum(st[++sp]);
1979 if (killpg(proc,val)) /* BSD */
1981 if (kill(-proc,val)) /* SYSV */
1988 if (kill((int)(str_gnum(st[++sp])),val))
1996 taintproper("Insecure dependency in unlink");
2000 s = str_get(st[++sp]);
2001 if (euid || unsafe) {
2005 else { /* don't let root wipe out directories without -U */
2007 if (lstat(s,&statbuf) < 0 ||
2009 if (stat(s,&statbuf) < 0 ||
2011 (statbuf.st_mode & S_IFMT) == S_IFDIR )
2022 taintproper("Insecure dependency in utime");
2026 struct utimbuf utbuf;
2034 Zero(&utbuf, sizeof utbuf, char);
2035 utbuf.actime = (long)str_gnum(st[++sp]); /* time accessed */
2036 utbuf.modtime = (long)str_gnum(st[++sp]); /* time modified */
2041 if (utime(str_get(st[++sp]),&utbuf))
2053 /* Do the permissions allow some operation? Assumes statcache already set. */
2056 cando(bit, effective, statbufp)
2059 register struct stat *statbufp;
2061 if ((effective ? euid : uid) == 0) { /* root is special */
2062 if (bit == S_IEXEC) {
2063 if (statbufp->st_mode & 0111 ||
2064 (statbufp->st_mode & S_IFMT) == S_IFDIR )
2068 return TRUE; /* root reads and writes anything */
2071 if (statbufp->st_uid == (effective ? euid : uid) ) {
2072 if (statbufp->st_mode & bit)
2073 return TRUE; /* ok as "user" */
2075 else if (ingroup((int)statbufp->st_gid,effective)) {
2076 if (statbufp->st_mode & bit >> 3)
2077 return TRUE; /* ok as "group" */
2079 else if (statbufp->st_mode & bit >> 6)
2080 return TRUE; /* ok as "other" */
2085 ingroup(testgid,effective)
2089 if (testgid == (effective ? egid : gid))
2096 GIDTYPE gary[NGROUPS];
2099 anum = getgroups(NGROUPS,gary);
2101 if (gary[anum] == testgid)