1 /* $Header: eval.c,v 2.0 88/06/05 00:08:48 root Exp $
4 * Revision 2.0 88/06/05 00:08:48 root
5 * Baseline version 2.0.
18 static void (*ihand)();
19 static void (*qhand)();
21 static int (*ihand)();
22 static int (*qhand)();
29 eval(arg,retary,sargoff)
31 STR ***retary; /* where to return an array to, null if nowhere */
32 int sargoff; /* how many elements in sarg are already assigned */
41 register STR **sarg = quicksarg;
48 unsigned long tmplong;
55 bool assigning = FALSE;
56 double exp(), log(), sqrt(), modf();
57 char *crypt(), *getenv();
61 str = arg->arg_ptr.arg_str;
62 optype = arg->arg_type;
63 maxsarg = maxarg = arg->arg_len;
64 if (maxsarg > 3 || retary) {
65 if (sargoff >= 0) { /* array already exists, just append to it */
67 sarg = (STR **)saferealloc((char*)*retary,
68 (maxsarg+sargoff+2+cushion) * sizeof(STR*)) + sargoff;
69 /* Note that sarg points into the middle of the array */
72 sargoff = cushion = 0;
73 sarg = (STR **)safemalloc((maxsarg+2) * sizeof(STR*));
81 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
83 debname[dlevel] = opname[optype][0];
84 debdelim[dlevel++] = ':';
87 for (anum = 1; anum <= maxarg; anum++) {
88 argflags = arg[anum].arg_flags;
89 if (argflags & AF_SPECIAL)
91 argtype = arg[anum].arg_type;
92 argptr = arg[anum].arg_ptr;
105 deb("%d.EXPR =>\n",anum);
109 (optype == O_LIST || optype == O_ITEM2 || optype == O_ITEM3)) {
110 *retary = sarg - sargoff;
111 eval(argptr.arg_arg, retary, anum - 1 + sargoff);
112 sarg = *retary; /* they do realloc it... */
113 argtype = maxarg - anum; /* how many left? */
114 maxsarg = (int)(str_gnum(sarg[0])) + argtype;
115 sargoff = maxsarg - maxarg;
116 if (argtype > 9 - cushion) { /* we don't have room left */
117 sarg = (STR **)saferealloc((char*)sarg,
118 (maxsarg+2+cushion) * sizeof(STR*));
123 sarg[anum] = eval(argptr.arg_arg, Null(STR***),-1);
129 deb("%d.CMD (%lx) =>\n",anum,argptr.arg_cmd);
132 sarg[anum] = cmd_exec(argptr.arg_cmd);
135 sarg[anum] = STAB_STR(argptr.arg_stab);
138 sprintf(buf,"STAB $%s",argptr.arg_stab->stab_name);
147 deb("%d.LEXPR =>\n",anum);
150 str = eval(argptr.arg_arg,Null(STR***),-1);
152 fatal("panic: A_LEXPR");
157 sprintf(buf,"LVAL $%s",argptr.arg_stab->stab_name);
161 str = STAB_STR(argptr.arg_stab);
163 fatal("panic: A_LVAL");
166 if (argflags & AF_PRE) {
167 if (argflags & AF_UP)
173 str = arg->arg_ptr.arg_str;
175 else if (argflags & AF_POST) {
176 sarg[anum] = str_static(str);
177 if (argflags & AF_UP)
182 str = arg->arg_ptr.arg_str;
190 argptr.arg_stab->stab_array->ary_magic;
195 fatal("panic: A_LEXPR");
198 stab = argptr.arg_stab;
199 sarg[anum] = stab->stab_array->ary_magic;
200 str_numset(sarg[anum],(double)(stab->stab_array->ary_fill+arybase));
206 sarg[anum] = argptr.arg_str;
212 (void) interp(str,str_get(argptr.arg_str));
219 tmps = str_get(argptr.arg_str);
220 fp = popen(str_get(interp(str,tmps)),"r");
221 tmpstr = str_new(80);
224 while (str_gets(tmpstr,fp) != Nullch) {
225 str_scat(str,tmpstr);
227 statusvalue = pclose(fp);
239 last_in_stab = stabent(str_get(STAB_STR(argptr.arg_stab)),TRUE);
242 argflags |= AF_POST; /* enable newline chopping */
244 last_in_stab = argptr.arg_stab;
247 if (last_in_stab->stab_io) {
248 fp = last_in_stab->stab_io->fp;
250 if (last_in_stab->stab_io->flags & IOF_ARGV) {
251 if (last_in_stab->stab_io->flags & IOF_START) {
252 last_in_stab->stab_io->flags &= ~IOF_START;
253 last_in_stab->stab_io->lines = 0;
254 if (alen(last_in_stab->stab_array) < 0) {
255 tmpstr = str_make("-"); /* assume stdin */
256 apush(last_in_stab->stab_array, tmpstr);
259 fp = nextargv(last_in_stab);
260 if (!fp) /* Note: fp != last_in_stab->stab_io->fp */
261 do_close(last_in_stab,FALSE); /* now it does */
263 else if (argtype == A_GLOB) {
264 (void) interp(str,str_get(last_in_stab->stab_val));
267 sprintf(tokenbuf,"%s|",tmps+1);
270 sprintf(tokenbuf, "%s", tmps+1);
272 sprintf(tokenbuf, "echo %s", tmps);
274 "|tr -s ' \t\f\r' '\\012\\012\\012\\012'|");
276 do_open(last_in_stab,tokenbuf);
277 fp = last_in_stab->stab_io->fp;
282 warn("Read on closed filehandle <%s>",last_in_stab->stab_name);
285 sarg[anum] = &str_no;
286 else if (!str_gets(str,fp)) {
287 if (last_in_stab->stab_io->flags & IOF_ARGV) {
288 fp = nextargv(last_in_stab);
291 do_close(last_in_stab,FALSE);
292 last_in_stab->stab_io->flags |= IOF_START;
294 else if (argflags & AF_POST) {
295 do_close(last_in_stab,FALSE);
300 sarg[anum] = &str_no;
303 maxsarg = maxarg + sargoff;
308 last_in_stab->stab_io->lines++;
310 if (argflags & AF_POST) {
311 if (str->str_cur > 0)
313 str->str_ptr[str->str_cur] = '\0';
316 sarg[anum] = str_static(sarg[anum]);
319 maxarg = anum + anum;
320 maxsarg = maxarg + sargoff;
321 sarg = (STR **)saferealloc((char*)(sarg-sargoff),
322 (maxsarg+2+cushion) * sizeof(STR*)) + sargoff;
329 maxsarg = maxarg + sargoff;
338 deb("%d.%s = '%s'\n",anum,tmps,str_peek(sarg[anum]));
343 if (maxarg > arg->arg_len)
346 str_sset(str,sarg[1]);
350 if (str != sarg[--anum])
351 str_sset(str,sarg[anum]);
355 if (str != sarg[--anum])
356 str_sset(str,sarg[anum]);
361 str_sset(str,sarg[1]);
362 str_scat(str,sarg[2]);
367 str_sset(str,sarg[1]);
368 anum = (int)str_gnum(sarg[2]);
371 str_sset(tmpstr,str);
373 str_scat(str,tmpstr);
376 str_sset(str,&str_no);
380 str_sset(str, do_match(arg,
381 retary,sarg,&maxsarg,sargoff,cushion));
383 sarg = *retary; /* they realloc it */
389 str_sset(str, do_match(arg,
390 retary,sarg,&maxsarg,sargoff,cushion));
392 sarg = *retary; /* they realloc it */
393 goto array_return; /* ignore negation */
395 str_set(str, str_true(str) ? No : Yes);
399 value = (double) do_subst(str, arg);
400 str = arg->arg_ptr.arg_str;
403 str_set(arg->arg_ptr.arg_str, do_subst(str, arg) ? No : Yes);
404 str = arg->arg_ptr.arg_str;
407 if (arg[1].arg_flags & AF_SPECIAL)
408 do_assign(str,arg,sarg);
411 str_sset(str, sarg[2]);
417 tmps += str->str_cur - (str->str_cur != 0);
418 str_set(arg->arg_ptr.arg_str,tmps); /* remember last char */
419 *tmps = '\0'; /* wipe it out */
420 str->str_cur = tmps - str->str_ptr;
422 str = arg->arg_ptr.arg_str;
425 value = (double)do_study(str);
426 str = arg->arg_ptr.arg_str;
429 value = str_gnum(sarg[1]);
430 value *= str_gnum(sarg[2]);
433 if ((value = str_gnum(sarg[2])) == 0.0)
434 fatal("Illegal division by zero");
435 value = str_gnum(sarg[1]) / value;
438 if ((tmplong = (unsigned long) str_gnum(sarg[2])) == 0L)
439 fatal("Illegal modulus zero");
440 value = str_gnum(sarg[1]);
441 value = (double)(((unsigned long)value) % tmplong);
444 value = str_gnum(sarg[1]);
445 value += str_gnum(sarg[2]);
448 value = str_gnum(sarg[1]);
449 value -= str_gnum(sarg[2]);
452 value = str_gnum(sarg[1]);
453 anum = (int)str_gnum(sarg[2]);
454 value = (double)(((unsigned long)value) << anum);
457 value = str_gnum(sarg[1]);
458 anum = (int)str_gnum(sarg[2]);
459 value = (double)(((unsigned long)value) >> anum);
462 value = str_gnum(sarg[1]);
463 value = (double)(value < str_gnum(sarg[2]));
466 value = str_gnum(sarg[1]);
467 value = (double)(value > str_gnum(sarg[2]));
470 value = str_gnum(sarg[1]);
471 value = (double)(value <= str_gnum(sarg[2]));
474 value = str_gnum(sarg[1]);
475 value = (double)(value >= str_gnum(sarg[2]));
478 value = str_gnum(sarg[1]);
479 value = (double)(value == str_gnum(sarg[2]));
482 value = str_gnum(sarg[1]);
483 value = (double)(value != str_gnum(sarg[2]));
486 value = str_gnum(sarg[1]);
487 value = (double)(((unsigned long)value) &
488 (unsigned long)str_gnum(sarg[2]));
491 value = str_gnum(sarg[1]);
492 value = (double)(((unsigned long)value) ^
493 (unsigned long)str_gnum(sarg[2]));
496 value = str_gnum(sarg[1]);
497 value = (double)(((unsigned long)value) |
498 (unsigned long)str_gnum(sarg[2]));
501 if (str_true(sarg[1])) {
504 argflags = arg[anum].arg_flags;
505 argtype = arg[anum].arg_type;
506 argptr = arg[anum].arg_ptr;
512 str_sset(str, sarg[1]);
520 if (str_true(sarg[1])) {
522 str_sset(str, sarg[1]);
532 argflags = arg[anum].arg_flags;
533 argtype = arg[anum].arg_type;
534 argptr = arg[anum].arg_ptr;
539 anum = (str_true(sarg[1]) ? 2 : 3);
540 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
541 argflags = arg[anum].arg_flags;
542 argtype = arg[anum].arg_type;
543 argptr = arg[anum].arg_ptr;
550 value = -str_gnum(sarg[1]);
553 value = (double) !str_true(sarg[1]);
556 value = (double) ~(long)str_gnum(sarg[1]);
559 if (arg[1].arg_type == A_LVAL)
560 defoutstab = arg[1].arg_ptr.arg_stab;
562 defoutstab = stabent(str_get(sarg[1]),TRUE);
563 if (!defoutstab->stab_io)
564 defoutstab->stab_io = stio_new();
565 curoutstab = defoutstab;
566 str_set(str,curoutstab->stab_io->fp ? Yes : No);
572 else if (arg[1].arg_type == A_LVAL)
573 stab = arg[1].arg_ptr.arg_stab;
575 stab = stabent(str_get(sarg[1]),TRUE);
576 if (!stab->stab_io) {
582 fp = stab->stab_io->fp;
584 if (stab->stab_io->fmt_stab)
585 form = stab->stab_io->fmt_stab->stab_form;
587 form = stab->stab_form;
593 format(&outrec,form);
594 do_write(&outrec,stab->stab_io);
595 if (stab->stab_io->flags & IOF_FLUSH)
601 if (arg[1].arg_type == A_WORD)
602 stab = arg[1].arg_ptr.arg_stab;
604 stab = stabent(str_get(sarg[1]),TRUE);
605 if (do_open(stab,str_get(sarg[2]))) {
606 value = (double)forkprocess;
607 stab->stab_io->lines = 0;
615 value = (double) do_trans(str,arg);
616 str = arg->arg_ptr.arg_str;
619 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
620 str = arg->arg_ptr.arg_str;
623 if (arg[1].arg_type == A_WORD)
624 stab = arg[1].arg_ptr.arg_stab;
626 stab = stabent(str_get(sarg[1]),TRUE);
627 str_set(str, do_close(stab,TRUE) ? Yes : No );
631 str_sset(str,do_each(arg[1].arg_ptr.arg_stab->stab_hash,
632 retary,sarg,&maxsarg,sargoff,cushion));
634 sarg = *retary; /* they realloc it */
641 value = (double) do_kv(arg[1].arg_ptr.arg_stab->stab_hash, optype,
642 retary,sarg,&maxsarg,sargoff,cushion);
644 sarg = *retary; /* they realloc it */
650 ary = arg[1].arg_ptr.arg_stab->stab_array;
651 maxarg = ary->ary_fill;
652 maxsarg = maxarg + sargoff;
653 if (retary) { /* array wanted */
654 sarg = (STR **)saferealloc((char*)(sarg-sargoff),
655 (maxsarg+3+cushion)*sizeof(STR*)) + sargoff;
656 for (anum = 0; anum <= maxarg; anum++) {
657 sarg[anum+1] = str = afetch(ary,anum);
664 str = afetch(ary,maxarg);
667 str = afetch(arg[2].arg_ptr.arg_stab->stab_array,
668 ((int)str_gnum(sarg[1])) - arybase);
673 tmpstab = arg[2].arg_ptr.arg_stab; /* XXX */
674 str = hdelete(tmpstab->stab_hash,str_get(sarg[1]));
679 tmpstab = arg[2].arg_ptr.arg_stab; /* XXX */
680 str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
685 anum = ((int)str_gnum(sarg[1])) - arybase;
686 str = afetch(arg[2].arg_ptr.arg_stab->stab_array,anum);
687 if (!str || str == &str_no) {
689 astore(arg[2].arg_ptr.arg_stab->stab_array,anum,str);
693 tmpstab = arg[2].arg_ptr.arg_stab;
694 str = hfetch(tmpstab->stab_hash,str_get(sarg[1]));
697 hstore(tmpstab->stab_hash,str_get(sarg[1]),str);
699 if (tmpstab == envstab) { /* heavy wizardry going on here */
700 str->str_link.str_magic = tmpstab;/* str is now magic */
701 envname = savestr(str_get(sarg[1]));
702 /* he threw the brick up into the air */
704 else if (tmpstab == sigstab) { /* same thing, only different */
705 str->str_link.str_magic = tmpstab;
706 signame = savestr(str_get(sarg[1]));
710 if (arg[1].arg_flags & AF_SPECIAL)
711 str = do_push(arg,arg[2].arg_ptr.arg_stab->stab_array);
713 str = str_new(0); /* must copy the STR */
714 str_sset(str,sarg[1]);
715 apush(arg[2].arg_ptr.arg_stab->stab_array,str);
719 str = apop(arg[1].arg_ptr.arg_stab->stab_array);
725 *(arg->arg_ptr.arg_str) = *str;
727 bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
729 safefree((char*)str);
730 str = arg->arg_ptr.arg_str;
733 str = ashift(arg[1].arg_ptr.arg_stab->stab_array);
739 *(arg->arg_ptr.arg_str) = *str;
741 bcopy((char*)str, (char*)arg->arg_ptr.arg_str, sizeof *str);
743 safefree((char*)str);
744 str = arg->arg_ptr.arg_str;
747 value = (double) do_split(arg[2].arg_ptr.arg_spat,
748 retary,sarg,&maxsarg,sargoff,cushion);
750 sarg = *retary; /* they realloc it */
755 value = (double) str_len(sarg[1]);
758 sarg[maxsarg+1] = Nullstr;
759 do_sprintf(str,arg->arg_len,sarg);
762 anum = ((int)str_gnum(sarg[2])) - arybase;
763 for (tmps = str_get(sarg[1]); *tmps && anum > 0; tmps++,anum--) ;
764 anum = (int)str_gnum(sarg[3]);
765 if (anum >= 0 && strlen(tmps) > anum)
766 str_nset(str, tmps, anum);
771 if (arg[2].arg_flags & AF_SPECIAL && arg[2].arg_type == A_EXPR)
772 do_join(arg,str_get(sarg[1]),str);
774 ajoin(arg[2].arg_ptr.arg_stab->stab_array,str_get(sarg[1]),str);
777 tmps = str_get(sarg[1]);
778 value = (double) strLT(tmps,str_get(sarg[2]));
781 tmps = str_get(sarg[1]);
782 value = (double) strGT(tmps,str_get(sarg[2]));
785 tmps = str_get(sarg[1]);
786 value = (double) strLE(tmps,str_get(sarg[2]));
789 tmps = str_get(sarg[1]);
790 value = (double) strGE(tmps,str_get(sarg[2]));
793 tmps = str_get(sarg[1]);
794 value = (double) strEQ(tmps,str_get(sarg[2]));
797 tmps = str_get(sarg[1]);
798 value = (double) strNE(tmps,str_get(sarg[2]));
801 str_sset(str,do_subr(arg,sarg));
808 if (arg[2].arg_type == A_WORD)
809 stab = arg[2].arg_ptr.arg_stab;
811 stab = stabent(str_get(sarg[2]),TRUE);
815 value = (double)do_sort(arg,stab,
816 retary,sarg,&maxsarg,sargoff,cushion);
818 sarg = *retary; /* they realloc it */
827 if (arg[2].arg_type == A_WORD)
828 stab = arg[2].arg_ptr.arg_stab;
830 stab = stabent(str_get(sarg[2]),TRUE);
834 if (!stab->stab_io || !(fp = stab->stab_io->fp))
837 if (arg[1].arg_flags & AF_SPECIAL)
838 value = (double)do_aprint(arg,fp);
840 value = (double)do_print(sarg[1],fp);
841 if (ors && optype == O_PRINT)
844 if (stab->stab_io->flags & IOF_FLUSH)
849 tmps = str_get(sarg[1]);
851 tmps = getenv("HOME");
853 tmps = getenv("LOGDIR");
854 value = (double)(chdir(tmps) >= 0);
857 tmps = str_get(sarg[1]);
860 fatal("%s",str_get(sarg[1]));
864 exit((int)str_gnum(sarg[1]));
868 str_reset(str_get(sarg[1]));
872 if (arg->arg_flags & AF_LOCAL)
873 savelist(sarg,maxsarg);
875 str = sarg[maxsarg]; /* unwanted list, return last item */
884 else if (arg[1].arg_type == A_WORD)
885 stab = arg[1].arg_ptr.arg_stab;
887 stab = stabent(str_get(sarg[1]),TRUE);
888 str_set(str, do_eof(stab) ? Yes : No);
894 else if (arg[1].arg_type == A_WORD)
895 stab = arg[1].arg_ptr.arg_stab;
897 stab = stabent(str_get(sarg[1]),TRUE);
898 value = (double)do_tell(stab);
901 if (arg[1].arg_type == A_WORD)
902 stab = arg[1].arg_ptr.arg_stab;
904 stab = stabent(str_get(sarg[1]),TRUE);
905 value = str_gnum(sarg[2]);
906 str_set(str, do_seek(stab,
907 (long)value, (int)str_gnum(sarg[3]) ) ? Yes : No);
914 tmps = str_get(sarg[1]);
915 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
916 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
919 deb("(Skipping label #%d %s)\n",loop_ptr,
920 loop_stack[loop_ptr].loop_label);
927 deb("(Found label #%d %s)\n",loop_ptr,
928 loop_stack[loop_ptr].loop_label);
933 fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
934 longjmp(loop_stack[loop_ptr].loop_env, optype);
935 case O_GOTO:/* shudder */
936 goto_targ = str_get(sarg[1]);
939 tmps = str_get(sarg[1]);
940 if (!(tmps2 = fbminstr(tmps, tmps + sarg[1]->str_cur, sarg[2])))
941 value = (double)(-1 + arybase);
943 value = (double)(tmps2 - tmps + arybase);
946 value = (double) time(Null(long*));
949 value = (double) do_tms(retary,sarg,&maxsarg,sargoff,cushion);
951 sarg = *retary; /* they realloc it */
956 when = (long)str_gnum(sarg[1]);
957 value = (double)do_time(localtime(&when),
958 retary,sarg,&maxsarg,sargoff,cushion);
960 sarg = *retary; /* they realloc it */
965 when = (long)str_gnum(sarg[1]);
966 value = (double)do_time(gmtime(&when),
967 retary,sarg,&maxsarg,sargoff,cushion);
969 sarg = *retary; /* they realloc it */
974 value = (double) do_stat(arg,
975 retary,sarg,&maxsarg,sargoff,cushion);
977 sarg = *retary; /* they realloc it */
983 tmps = str_get(sarg[1]);
984 str_set(str,crypt(tmps,str_get(sarg[2])));
987 "The crypt() function is unimplemented due to excessive paranoia.");
991 value = exp(str_gnum(sarg[1]));
994 value = log(str_gnum(sarg[1]));
997 value = sqrt(str_gnum(sarg[1]));
1000 value = str_gnum(sarg[1]);
1004 modf(-value,&value);
1009 value = (double) *str_get(sarg[1]);
1012 tmps = str_get(sarg[1]);
1014 if (!tmps || !*tmps)
1015 sleep((32767<<16)+32767);
1017 sleep((unsigned)atoi(tmps));
1018 value = (double)when;
1020 value = ((double)when) - value;
1023 if (str_true(sarg[1])) {
1024 str_numset(str,0.0);
1026 arg->arg_type = optype = O_FLOP;
1027 arg[2].arg_flags &= ~AF_SPECIAL;
1028 arg[1].arg_flags |= AF_SPECIAL;
1029 argflags = arg[2].arg_flags;
1030 argtype = arg[2].arg_type;
1031 argptr = arg[2].arg_ptr;
1038 if (str_true(sarg[2])) {
1039 arg->arg_type = O_FLIP;
1040 arg[1].arg_flags &= ~AF_SPECIAL;
1041 arg[2].arg_flags |= AF_SPECIAL;
1046 value = (double)fork();
1049 ihand = signal(SIGINT, SIG_IGN);
1050 qhand = signal(SIGQUIT, SIG_IGN);
1051 value = (double)wait(&argflags);
1052 signal(SIGINT, ihand);
1053 signal(SIGQUIT, qhand);
1054 statusvalue = (unsigned short)argflags;
1057 while ((anum = vfork()) == -1) {
1058 if (errno != EAGAIN) {
1065 ihand = signal(SIGINT, SIG_IGN);
1066 qhand = signal(SIGQUIT, SIG_IGN);
1067 while ((argtype = wait(&argflags)) != anum && argtype != -1)
1069 signal(SIGINT, ihand);
1070 signal(SIGQUIT, qhand);
1071 statusvalue = (unsigned short)argflags;
1075 value = (double)((unsigned int)argflags & 0xffff);
1079 if (arg[1].arg_flags & AF_SPECIAL)
1080 value = (double)do_aexec(arg);
1082 value = (double)do_exec(str_static(sarg[1]));
1086 if (arg[1].arg_flags & AF_SPECIAL)
1087 value = (double)do_aexec(arg);
1089 value = (double)do_exec(str_static(sarg[1]));
1101 tmps = str_get(sarg[1]);
1110 case '0': case '1': case '2': case '3': case '4':
1111 case '5': case '6': case '7':
1113 anum += *tmps++ & 15;
1115 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1116 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1120 anum += (*tmps++ & 7) + 9;
1129 value = (double)anum;
1136 if (arg[1].arg_flags & AF_SPECIAL)
1137 value = (double)apply(optype,arg,Null(STR**));
1140 value = (double)apply(optype,arg,sarg);
1144 value = (double)umask((int)str_gnum(sarg[1]));
1147 tmps = str_get(sarg[1]);
1149 value = (double)(rename(tmps,str_get(sarg[2])) >= 0);
1151 tmps2 = str_get(sarg[2]);
1152 if (euid || stat(tmps2,&statbuf) < 0 ||
1153 (statbuf.st_mode & S_IFMT) != S_IFDIR )
1154 UNLINK(tmps2); /* avoid unlinking a directory */
1155 if (!(anum = link(tmps,tmps2)))
1156 anum = UNLINK(tmps);
1157 value = (double)(anum >= 0);
1161 tmps = str_get(sarg[1]);
1162 value = (double)(link(tmps,str_get(sarg[2])) >= 0);
1165 ary = arg[2].arg_ptr.arg_stab->stab_array;
1166 if (arg[1].arg_flags & AF_SPECIAL)
1167 do_unshift(arg,ary);
1169 str = str_new(0); /* must copy the STR */
1170 str_sset(str,sarg[1]);
1174 value = (double)(ary->ary_fill + 1);
1179 do_eval(arg[1].arg_type != A_NULL ? sarg[1] : defstab->stab_val,
1209 if (mystat(arg,sarg[1]) < 0)
1211 if (cando(anum,argtype))
1216 if (mystat(arg,sarg[1]) >= 0)
1223 if (mystat(arg,sarg[1]) >= 0 &&
1224 statbuf.st_uid == (optype == O_FTEOWNED ? euid : uid) )
1230 if (mystat(arg,sarg[1]) >= 0 && !statbuf.st_size)
1236 if (mystat(arg,sarg[1]) >= 0 && statbuf.st_size)
1245 goto check_file_type;
1252 goto check_file_type;
1255 goto check_file_type;
1258 goto check_file_type;
1262 if (mystat(arg,sarg[1]) >= 0 &&
1263 (statbuf.st_mode & S_IFMT) == anum )
1271 goto check_file_type;
1278 if (lstat(str_get(sarg[1]),&statbuf) >= 0 &&
1279 (statbuf.st_mode & S_IFMT) == S_IFLNK )
1287 tmps = str_get(sarg[1]);
1288 value = (double)(symlink(tmps,str_get(sarg[2])) >= 0);
1291 fatal("Unsupported function symlink()");
1302 if (mystat(arg,sarg[1]) >= 0 && statbuf.st_mode & anum)
1308 if (arg[1].arg_flags & AF_SPECIAL) {
1309 stab = arg[1].arg_ptr.arg_stab;
1313 stab = stabent(tmps = str_get(sarg[1]),FALSE);
1314 if (stab && stab->stab_io && stab->stab_io->fp)
1315 anum = fileno(stab->stab_io->fp);
1316 else if (isdigit(*tmps))
1327 str = do_fttext(arg,sarg[1]);
1332 maxsarg = sargoff + 1;
1338 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
1348 deb("%s RETURNS ARRAY OF %d ARGS\n",opname[optype],maxsarg-sargoff);
1354 str_numset(str,value);
1358 maxsarg = sargoff + 1;
1364 deb("%s RETURNS \"%f\"\n",opname[optype],value);
1370 if (sarg != quicksarg) {
1372 sarg[0] = &str_args;
1373 str_numset(sarg[0], (double)(maxsarg));
1374 sarg[maxsarg+1] = Nullstr;
1375 *retary = sarg; /* up to them to free it */
1378 safefree((char*)sarg);
1384 ingroup(gid,effective)
1388 if (gid == (effective ? getegid() : getgid()))
1395 GIDTYPE gary[NGROUPS];
1398 anum = getgroups(NGROUPS,gary);
1400 if (gary[anum] == gid)
1407 /* Do the permissions allow some operation? Assumes statbuf already set. */
1410 cando(bit, effective)
1414 if ((effective ? euid : uid) == 0) { /* root is special */
1415 if (bit == S_IEXEC) {
1416 if (statbuf.st_mode & 0111 ||
1417 (statbuf.st_mode & S_IFMT) == S_IFDIR )
1421 return TRUE; /* root reads and writes anything */
1424 if (statbuf.st_uid == (effective ? euid : uid) ) {
1425 if (statbuf.st_mode & bit)
1426 return TRUE; /* ok as "user" */
1428 else if (ingroup((int)statbuf.st_gid,effective)) {
1429 if (statbuf.st_mode & bit >> 3)
1430 return TRUE; /* ok as "group" */
1432 else if (statbuf.st_mode & bit >> 6)
1433 return TRUE; /* ok as "other" */