perl 3.0 patch #14 patch #13, continued
[p5sagit/p5-mst-13.2.git] / eval.c
CommitLineData
79a0689e 1/* $Header: eval.c,v 3.0.1.5 90/03/12 16:37:40 lwall Locked $
a687059c 2 *
3 * Copyright (c) 1989, Larry Wall
4 *
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.
378cc40b 7 *
8 * $Log: eval.c,v $
79a0689e 9 * Revision 3.0.1.5 90/03/12 16:37:40 lwall
10 * patch13: undef $/ didn't work as advertised
11 * patch13: added list slice operator (LIST)[LIST]
12 * patch13: added splice operator: @oldelems = splice(@array,$offset,$len,LIST)
13 *
afd9f252 14 * Revision 3.0.1.4 90/02/28 17:36:59 lwall
15 * patch9: added pipe function
16 * patch9: a return in scalar context wouldn't return array
17 * patch9: !~ now always returns scalar even in array context
18 * patch9: some machines can't cast float to long with high bit set
19 * patch9: piped opens returned undef in child
20 * patch9: @array in scalar context now returns length of array
21 * patch9: chdir; coredumped
22 * patch9: wait no longer ignores signals
23 * patch9: mkdir now handles odd versions of /bin/mkdir
24 * patch9: -l FILEHANDLE now disallowed
25 *
663a0e37 26 * Revision 3.0.1.3 89/12/21 20:03:05 lwall
27 * patch7: errno may now be a macro with an lvalue
28 * patch7: ANSI strerror() is now supported
29 * patch7: send() didn't allow a TO argument
30 * patch7: ord() now always returns positive even on signed char machines
31 *
0d3e774c 32 * Revision 3.0.1.2 89/11/17 15:19:34 lwall
663a0e37 33 * patch5: constant numeric subscripts get lost inside ?:
0d3e774c 34 *
bf38876a 35 * Revision 3.0.1.1 89/11/11 04:31:51 lwall
36 * patch2: mkdir and rmdir needed to quote argument when passed to shell
37 * patch2: mkdir and rmdir now return better error codes
38 * patch2: fileno, seekdir, rewinddir and closedir now disallow defaults
39 *
a687059c 40 * Revision 3.0 89/10/18 15:17:04 lwall
41 * 3.0 baseline
378cc40b 42 *
43 */
44
45#include "EXTERN.h"
46#include "perl.h"
47
48#include <signal.h>
378cc40b 49
a687059c 50#ifdef I_VFORK
51# include <vfork.h>
52#endif
53
378cc40b 54#ifdef VOIDSIG
55static void (*ihand)();
56static void (*qhand)();
57#else
58static int (*ihand)();
59static int (*qhand)();
60#endif
61
62ARG *debarg;
63STR str_args;
a687059c 64static STAB *stab2;
65static STIO *stio;
66static struct lstring *lstr;
79a0689e 67static int old_record_separator;
afd9f252 68extern int wantarray;
378cc40b 69
a687059c 70double sin(), cos(), atan2(), pow();
71
72char *getlogin();
73
a687059c 74int
75eval(arg,gimme,sp)
378cc40b 76register ARG *arg;
a687059c 77int gimme;
78register int sp;
378cc40b 79{
80 register STR *str;
81 register int anum;
82 register int optype;
a687059c 83 register STR **st;
378cc40b 84 int maxarg;
378cc40b 85 double value;
378cc40b 86 register char *tmps;
87 char *tmps2;
88 int argflags;
89 int argtype;
90 union argptr argptr;
a687059c 91 int arglast[8]; /* highest sp for arg--valid only for non-O_LIST args */
378cc40b 92 unsigned long tmplong;
93 long when;
94 FILE *fp;
95 STR *tmpstr;
96 FCMD *form;
97 STAB *stab;
98 ARRAY *ary;
99 bool assigning = FALSE;
100 double exp(), log(), sqrt(), modf();
101 char *crypt(), *getenv();
a687059c 102 extern void grow_dlevel();
378cc40b 103
104 if (!arg)
a687059c 105 goto say_undef;
378cc40b 106 optype = arg->arg_type;
a687059c 107 maxarg = arg->arg_len;
108 arglast[0] = sp;
109 str = arg->arg_ptr.arg_str;
110 if (sp + maxarg > stack->ary_max)
111 astore(stack, sp + maxarg, Nullstr);
112 st = stack->ary_array;
113
378cc40b 114#ifdef DEBUGGING
115 if (debug) {
116 if (debug & 8) {
117 deb("%s (%lx) %d args:\n",opname[optype],arg,maxarg);
118 }
119 debname[dlevel] = opname[optype][0];
a687059c 120 debdelim[dlevel] = ':';
121 if (++dlevel >= dlmax)
122 grow_dlevel();
378cc40b 123 }
124#endif
378cc40b 125
a687059c 126#include "evalargs.xc"
127
128 st += arglast[0];
378cc40b 129 switch (optype) {
a687059c 130 case O_RCAT:
131 STABSET(str);
132 break;
378cc40b 133 case O_ITEM:
a687059c 134 if (gimme == G_ARRAY)
378cc40b 135 goto array_return;
a687059c 136 STR_SSET(str,st[1]);
378cc40b 137 STABSET(str);
138 break;
139 case O_ITEM2:
a687059c 140 if (gimme == G_ARRAY)
141 goto array_return;
142 --anum;
143 STR_SSET(str,st[arglast[anum]-arglast[0]]);
378cc40b 144 STABSET(str);
145 break;
146 case O_ITEM3:
a687059c 147 if (gimme == G_ARRAY)
148 goto array_return;
149 --anum;
150 STR_SSET(str,st[arglast[anum]-arglast[0]]);
378cc40b 151 STABSET(str);
152 break;
153 case O_CONCAT:
a687059c 154 STR_SSET(str,st[1]);
155 str_scat(str,st[2]);
378cc40b 156 STABSET(str);
157 break;
158 case O_REPEAT:
a687059c 159 STR_SSET(str,st[1]);
160 anum = (int)str_gnum(st[2]);
378cc40b 161 if (anum >= 1) {
afd9f252 162 tmpstr = Str_new(50, 0);
378cc40b 163 str_sset(tmpstr,str);
afd9f252 164 tmps = str_get(tmpstr); /* force to be string */
165 STR_GROW(str, (anum * str->str_cur) + 1);
166 repeatcpy(str->str_ptr, tmps, tmpstr->str_cur, anum);
79a0689e 167 str->str_cur *= anum;
168 str->str_ptr[str->str_cur] = '\0';
378cc40b 169 }
170 else
171 str_sset(str,&str_no);
172 STABSET(str);
173 break;
174 case O_MATCH:
a687059c 175 sp = do_match(str,arg,
176 gimme,arglast);
177 if (gimme == G_ARRAY)
378cc40b 178 goto array_return;
378cc40b 179 STABSET(str);
180 break;
181 case O_NMATCH:
a687059c 182 sp = do_match(str,arg,
afd9f252 183 G_SCALAR,arglast);
a687059c 184 str_sset(str, str_true(str) ? &str_no : &str_yes);
378cc40b 185 STABSET(str);
186 break;
187 case O_SUBST:
a687059c 188 sp = do_subst(str,arg,arglast[0]);
189 goto array_return;
378cc40b 190 case O_NSUBST:
a687059c 191 sp = do_subst(str,arg,arglast[0]);
378cc40b 192 str = arg->arg_ptr.arg_str;
a687059c 193 str_set(str, str_true(str) ? No : Yes);
194 goto array_return;
378cc40b 195 case O_ASSIGN:
a687059c 196 if (arg[1].arg_flags & AF_ARYOK) {
197 if (arg->arg_len == 1) {
198 arg->arg_type = O_LOCAL;
a687059c 199 goto local;
200 }
201 else {
202 arg->arg_type = O_AASSIGN;
203 goto aassign;
204 }
205 }
378cc40b 206 else {
a687059c 207 arg->arg_type = O_SASSIGN;
208 goto sassign;
378cc40b 209 }
a687059c 210 case O_LOCAL:
211 local:
212 arglast[2] = arglast[1]; /* push a null array */
213 /* FALL THROUGH */
214 case O_AASSIGN:
215 aassign:
216 sp = do_assign(arg,
217 gimme,arglast);
218 goto array_return;
219 case O_SASSIGN:
220 sassign:
221 STR_SSET(str, st[2]);
222 STABSET(str);
378cc40b 223 break;
224 case O_CHOP:
a687059c 225 st -= arglast[0];
378cc40b 226 str = arg->arg_ptr.arg_str;
a687059c 227 for (sp = arglast[0] + 1; sp <= arglast[1]; sp++)
228 do_chop(str,st[sp]);
229 st += arglast[0];
378cc40b 230 break;
a687059c 231 case O_DEFINED:
232 if (arg[1].arg_type & A_DONT) {
233 sp = do_defined(str,arg,
234 gimme,arglast);
235 goto array_return;
236 }
237 else if (str->str_pok || str->str_nok)
238 goto say_yes;
239 goto say_no;
240 case O_UNDEF:
241 if (arg[1].arg_type & A_DONT) {
242 sp = do_undef(str,arg,
243 gimme,arglast);
244 goto array_return;
245 }
246 else if (str != stab_val(defstab)) {
247 str->str_pok = str->str_nok = 0;
248 STABSET(str);
249 }
250 goto say_undef;
378cc40b 251 case O_STUDY:
a687059c 252 sp = do_study(str,arg,
253 gimme,arglast);
254 goto array_return;
255 case O_POW:
256 value = str_gnum(st[1]);
257 value = pow(value,str_gnum(st[2]));
378cc40b 258 goto donumset;
259 case O_MULTIPLY:
a687059c 260 value = str_gnum(st[1]);
261 value *= str_gnum(st[2]);
378cc40b 262 goto donumset;
263 case O_DIVIDE:
a687059c 264 if ((value = str_gnum(st[2])) == 0.0)
378cc40b 265 fatal("Illegal division by zero");
a687059c 266 value = str_gnum(st[1]) / value;
378cc40b 267 goto donumset;
268 case O_MODULO:
a687059c 269 tmplong = (long) str_gnum(st[2]);
270 if (tmplong == 0L)
378cc40b 271 fatal("Illegal modulus zero");
a687059c 272 when = (long)str_gnum(st[1]);
273#ifndef lint
274 if (when >= 0)
275 value = (double)(when % tmplong);
276 else
277 value = (double)(tmplong - (-when % tmplong));
278#endif
378cc40b 279 goto donumset;
280 case O_ADD:
a687059c 281 value = str_gnum(st[1]);
282 value += str_gnum(st[2]);
378cc40b 283 goto donumset;
284 case O_SUBTRACT:
a687059c 285 value = str_gnum(st[1]);
286 value -= str_gnum(st[2]);
378cc40b 287 goto donumset;
288 case O_LEFT_SHIFT:
a687059c 289 value = str_gnum(st[1]);
290 anum = (int)str_gnum(st[2]);
291#ifndef lint
afd9f252 292 value = (double)(((unsigned long)value) << anum);
a687059c 293#endif
378cc40b 294 goto donumset;
295 case O_RIGHT_SHIFT:
a687059c 296 value = str_gnum(st[1]);
297 anum = (int)str_gnum(st[2]);
298#ifndef lint
afd9f252 299 value = (double)(((unsigned long)value) >> anum);
a687059c 300#endif
378cc40b 301 goto donumset;
302 case O_LT:
a687059c 303 value = str_gnum(st[1]);
304 value = (value < str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 305 goto donumset;
306 case O_GT:
a687059c 307 value = str_gnum(st[1]);
308 value = (value > str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 309 goto donumset;
310 case O_LE:
a687059c 311 value = str_gnum(st[1]);
312 value = (value <= str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 313 goto donumset;
314 case O_GE:
a687059c 315 value = str_gnum(st[1]);
316 value = (value >= str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 317 goto donumset;
318 case O_EQ:
a687059c 319 if (dowarn) {
320 if ((!st[1]->str_nok && !looks_like_number(st[1])) ||
321 (!st[2]->str_nok && !looks_like_number(st[2])) )
322 warn("Possible use of == on string value");
323 }
324 value = str_gnum(st[1]);
325 value = (value == str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 326 goto donumset;
327 case O_NE:
a687059c 328 value = str_gnum(st[1]);
329 value = (value != str_gnum(st[2])) ? 1.0 : 0.0;
378cc40b 330 goto donumset;
331 case O_BIT_AND:
a687059c 332 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
333 value = str_gnum(st[1]);
334#ifndef lint
afd9f252 335 value = (double)(((unsigned long)value) &
336 (unsigned long)str_gnum(st[2]));
a687059c 337#endif
338 goto donumset;
339 }
340 else
341 do_vop(optype,str,st[1],st[2]);
342 break;
378cc40b 343 case O_XOR:
a687059c 344 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
345 value = str_gnum(st[1]);
346#ifndef lint
afd9f252 347 value = (double)(((unsigned long)value) ^
348 (unsigned long)str_gnum(st[2]));
a687059c 349#endif
350 goto donumset;
351 }
352 else
353 do_vop(optype,str,st[1],st[2]);
354 break;
378cc40b 355 case O_BIT_OR:
a687059c 356 if (!sawvec || st[1]->str_nok || st[2]->str_nok) {
357 value = str_gnum(st[1]);
358#ifndef lint
afd9f252 359 value = (double)(((unsigned long)value) |
360 (unsigned long)str_gnum(st[2]));
a687059c 361#endif
362 goto donumset;
363 }
364 else
365 do_vop(optype,str,st[1],st[2]);
366 break;
367/* use register in evaluating str_true() */
378cc40b 368 case O_AND:
a687059c 369 if (str_true(st[1])) {
378cc40b 370 anum = 2;
371 optype = O_ITEM2;
372 argflags = arg[anum].arg_flags;
a687059c 373 if (gimme == G_ARRAY)
374 argflags |= AF_ARYOK;
375 argtype = arg[anum].arg_type & A_MASK;
378cc40b 376 argptr = arg[anum].arg_ptr;
377 maxarg = anum = 1;
a687059c 378 sp = arglast[0];
379 st -= sp;
378cc40b 380 goto re_eval;
381 }
382 else {
383 if (assigning) {
a687059c 384 str_sset(str, st[1]);
378cc40b 385 STABSET(str);
386 }
387 else
a687059c 388 str = st[1];
378cc40b 389 break;
390 }
391 case O_OR:
a687059c 392 if (str_true(st[1])) {
378cc40b 393 if (assigning) {
a687059c 394 str_sset(str, st[1]);
378cc40b 395 STABSET(str);
396 }
397 else
a687059c 398 str = st[1];
378cc40b 399 break;
400 }
401 else {
402 anum = 2;
403 optype = O_ITEM2;
404 argflags = arg[anum].arg_flags;
a687059c 405 if (gimme == G_ARRAY)
406 argflags |= AF_ARYOK;
407 argtype = arg[anum].arg_type & A_MASK;
378cc40b 408 argptr = arg[anum].arg_ptr;
409 maxarg = anum = 1;
a687059c 410 sp = arglast[0];
411 st -= sp;
378cc40b 412 goto re_eval;
413 }
414 case O_COND_EXPR:
a687059c 415 anum = (str_true(st[1]) ? 2 : 3);
378cc40b 416 optype = (anum == 2 ? O_ITEM2 : O_ITEM3);
417 argflags = arg[anum].arg_flags;
a687059c 418 if (gimme == G_ARRAY)
419 argflags |= AF_ARYOK;
420 argtype = arg[anum].arg_type & A_MASK;
378cc40b 421 argptr = arg[anum].arg_ptr;
422 maxarg = anum = 1;
a687059c 423 sp = arglast[0];
424 st -= sp;
378cc40b 425 goto re_eval;
426 case O_COMMA:
a687059c 427 if (gimme == G_ARRAY)
428 goto array_return;
429 str = st[2];
378cc40b 430 break;
431 case O_NEGATE:
a687059c 432 value = -str_gnum(st[1]);
378cc40b 433 goto donumset;
434 case O_NOT:
a687059c 435 value = (double) !str_true(st[1]);
378cc40b 436 goto donumset;
437 case O_COMPLEMENT:
a687059c 438#ifndef lint
afd9f252 439 value = (double) ~(unsigned long)str_gnum(st[1]);
a687059c 440#endif
378cc40b 441 goto donumset;
442 case O_SELECT:
a687059c 443 tmps = stab_name(defoutstab);
444 if (maxarg > 0) {
445 if ((arg[1].arg_type & A_MASK) == A_WORD)
446 defoutstab = arg[1].arg_ptr.arg_stab;
447 else
448 defoutstab = stabent(str_get(st[1]),TRUE);
449 if (!stab_io(defoutstab))
450 stab_io(defoutstab) = stio_new();
451 curoutstab = defoutstab;
452 }
453 str_set(str, tmps);
378cc40b 454 STABSET(str);
455 break;
456 case O_WRITE:
457 if (maxarg == 0)
458 stab = defoutstab;
a687059c 459 else if ((arg[1].arg_type & A_MASK) == A_WORD) {
460 if (!(stab = arg[1].arg_ptr.arg_stab))
461 stab = defoutstab;
462 }
378cc40b 463 else
a687059c 464 stab = stabent(str_get(st[1]),TRUE);
465 if (!stab_io(stab)) {
378cc40b 466 str_set(str, No);
467 STABSET(str);
468 break;
469 }
470 curoutstab = stab;
a687059c 471 fp = stab_io(stab)->ofp;
378cc40b 472 debarg = arg;
a687059c 473 if (stab_io(stab)->fmt_stab)
474 form = stab_form(stab_io(stab)->fmt_stab);
378cc40b 475 else
a687059c 476 form = stab_form(stab);
378cc40b 477 if (!form || !fp) {
a687059c 478 if (dowarn) {
479 if (form)
480 warn("No format for filehandle");
481 else {
482 if (stab_io(stab)->ifp)
483 warn("Filehandle only opened for input");
484 else
485 warn("Write on closed filehandle");
486 }
487 }
378cc40b 488 str_set(str, No);
489 STABSET(str);
490 break;
491 }
a687059c 492 format(&outrec,form,sp);
493 do_write(&outrec,stab_io(stab),sp);
494 if (stab_io(stab)->flags & IOF_FLUSH)
495 (void)fflush(fp);
378cc40b 496 str_set(str, Yes);
497 STABSET(str);
498 break;
a687059c 499 case O_DBMOPEN:
500#ifdef SOME_DBM
501 if ((arg[1].arg_type & A_MASK) == A_WORD)
502 stab = arg[1].arg_ptr.arg_stab;
503 else
504 stab = stabent(str_get(st[1]),TRUE);
505 anum = (int)str_gnum(st[3]);
506 value = (double)hdbmopen(stab_hash(stab),str_get(st[2]),anum);
507 goto donumset;
508#else
509 fatal("No dbm or ndbm on this machine");
510#endif
511 case O_DBMCLOSE:
512#ifdef SOME_DBM
513 if ((arg[1].arg_type & A_MASK) == A_WORD)
514 stab = arg[1].arg_ptr.arg_stab;
515 else
516 stab = stabent(str_get(st[1]),TRUE);
517 hdbmclose(stab_hash(stab));
518 goto say_yes;
519#else
520 fatal("No dbm or ndbm on this machine");
521#endif
378cc40b 522 case O_OPEN:
a687059c 523 if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 524 stab = arg[1].arg_ptr.arg_stab;
525 else
a687059c 526 stab = stabent(str_get(st[1]),TRUE);
afd9f252 527 tmps = str_get(st[2]);
528 if (do_open(stab,tmps,st[2]->str_cur)) {
378cc40b 529 value = (double)forkprocess;
a687059c 530 stab_io(stab)->lines = 0;
378cc40b 531 goto donumset;
532 }
afd9f252 533 else if (forkprocess == 0) /* we are a new child */
534 goto say_zero;
378cc40b 535 else
a687059c 536 goto say_undef;
378cc40b 537 break;
538 case O_TRANS:
539 value = (double) do_trans(str,arg);
540 str = arg->arg_ptr.arg_str;
541 goto donumset;
542 case O_NTRANS:
543 str_set(arg->arg_ptr.arg_str, do_trans(str,arg) == 0 ? Yes : No);
544 str = arg->arg_ptr.arg_str;
545 break;
546 case O_CLOSE:
a687059c 547 if (maxarg == 0)
548 stab = defoutstab;
549 else if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 550 stab = arg[1].arg_ptr.arg_stab;
551 else
a687059c 552 stab = stabent(str_get(st[1]),TRUE);
378cc40b 553 str_set(str, do_close(stab,TRUE) ? Yes : No );
554 STABSET(str);
555 break;
556 case O_EACH:
a687059c 557 sp = do_each(str,stab_hash(arg[1].arg_ptr.arg_stab),
558 gimme,arglast);
559 goto array_return;
378cc40b 560 case O_VALUES:
561 case O_KEYS:
a687059c 562 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
563 gimme,arglast);
564 goto array_return;
565 case O_LARRAY:
566 str->str_nok = str->str_pok = 0;
567 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
568 str->str_state = SS_ARY;
569 break;
378cc40b 570 case O_ARRAY:
a687059c 571 ary = stab_array(arg[1].arg_ptr.arg_stab);
572 maxarg = ary->ary_fill + 1;
573 if (gimme == G_ARRAY) { /* array wanted */
574 sp = arglast[0];
575 st -= sp;
576 if (maxarg > 0 && sp + maxarg > stack->ary_max) {
577 astore(stack,sp + maxarg, Nullstr);
578 st = stack->ary_array;
378cc40b 579 }
a687059c 580 Copy(ary->ary_array, &st[sp+1], maxarg, STR*);
581 sp += maxarg;
582 goto array_return;
378cc40b 583 }
afd9f252 584 else {
585 value = (double)maxarg;
586 goto donumset;
587 }
a687059c 588 case O_AELEM:
0d3e774c 589 anum = ((int)str_gnum(st[2])) - arybase;
590 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,FALSE);
378cc40b 591 if (!str)
a687059c 592 goto say_undef;
378cc40b 593 break;
594 case O_DELETE:
a687059c 595 tmpstab = arg[1].arg_ptr.arg_stab;
596 tmps = str_get(st[2]);
597 str = hdelete(stab_hash(tmpstab),tmps,st[2]->str_cur);
598 if (tmpstab == envstab)
599 setenv(tmps,Nullch);
378cc40b 600 if (!str)
a687059c 601 goto say_undef;
602 break;
603 case O_LHASH:
604 str->str_nok = str->str_pok = 0;
605 str->str_u.str_stab = arg[1].arg_ptr.arg_stab;
606 str->str_state = SS_HASH;
378cc40b 607 break;
608 case O_HASH:
a687059c 609 if (gimme == G_ARRAY) { /* array wanted */
610 sp = do_kv(str,stab_hash(arg[1].arg_ptr.arg_stab), optype,
611 gimme,arglast);
612 goto array_return;
613 }
614 else {
615 tmpstab = arg[1].arg_ptr.arg_stab;
616 sprintf(buf,"%d/%d",stab_hash(tmpstab)->tbl_fill,
617 stab_hash(tmpstab)->tbl_max+1);
618 str_set(str,buf);
619 }
620 break;
621 case O_HELEM:
622 tmpstab = arg[1].arg_ptr.arg_stab;
623 tmps = str_get(st[2]);
624 str = hfetch(stab_hash(tmpstab),tmps,st[2]->str_cur,FALSE);
378cc40b 625 if (!str)
a687059c 626 goto say_undef;
378cc40b 627 break;
a687059c 628 case O_LAELEM:
629 anum = ((int)str_gnum(st[2])) - arybase;
630 str = afetch(stab_array(arg[1].arg_ptr.arg_stab),anum,TRUE);
631 if (!str)
632 fatal("Assignment to non-creatable value, subscript %d",anum);
378cc40b 633 break;
a687059c 634 case O_LHELEM:
635 tmpstab = arg[1].arg_ptr.arg_stab;
636 tmps = str_get(st[2]);
637 anum = st[2]->str_cur;
638 str = hfetch(stab_hash(tmpstab),tmps,anum,TRUE);
639 if (!str)
640 fatal("Assignment to non-creatable value, subscript \"%s\"",tmps);
641 if (tmpstab == envstab) /* heavy wizardry going on here */
642 str_magic(str, tmpstab, 'E', tmps, anum); /* str is now magic */
378cc40b 643 /* he threw the brick up into the air */
a687059c 644 else if (tmpstab == sigstab)
645 str_magic(str, tmpstab, 'S', tmps, anum);
646#ifdef SOME_DBM
647 else if (stab_hash(tmpstab)->tbl_dbm)
648 str_magic(str, tmpstab, 'D', tmps, anum);
649#endif
378cc40b 650 break;
79a0689e 651 case O_LSLICE:
652 anum = 2;
653 argtype = FALSE;
654 goto do_slice_already;
a687059c 655 case O_ASLICE:
79a0689e 656 anum = 1;
a687059c 657 argtype = FALSE;
658 goto do_slice_already;
659 case O_HSLICE:
79a0689e 660 anum = 0;
a687059c 661 argtype = FALSE;
662 goto do_slice_already;
663 case O_LASLICE:
79a0689e 664 anum = 1;
a687059c 665 argtype = TRUE;
666 goto do_slice_already;
667 case O_LHSLICE:
79a0689e 668 anum = 0;
a687059c 669 argtype = TRUE;
670 do_slice_already:
79a0689e 671 sp = do_slice(arg[1].arg_ptr.arg_stab,str,anum,argtype,
a687059c 672 gimme,arglast);
673 goto array_return;
79a0689e 674 case O_SPLICE:
675 sp = do_splice(stab_array(arg[1].arg_ptr.arg_stab),str,gimme,arglast);
676 goto array_return;
378cc40b 677 case O_PUSH:
a687059c 678 if (arglast[2] - arglast[1] != 1)
679 str = do_push(stab_array(arg[1].arg_ptr.arg_stab),arglast);
378cc40b 680 else {
a687059c 681 str = Str_new(51,0); /* must copy the STR */
682 str_sset(str,st[2]);
683 (void)apush(stab_array(arg[1].arg_ptr.arg_stab),str);
378cc40b 684 }
685 break;
686 case O_POP:
a687059c 687 str = apop(ary = stab_array(arg[1].arg_ptr.arg_stab));
688 goto staticalization;
378cc40b 689 case O_SHIFT:
a687059c 690 str = ashift(ary = stab_array(arg[1].arg_ptr.arg_stab));
691 staticalization:
692 if (!str)
693 goto say_undef;
694 if (ary->ary_flags & ARF_REAL)
695 (void)str_2static(str);
378cc40b 696 break;
a687059c 697 case O_UNPACK:
698 sp = do_unpack(str,gimme,arglast);
699 goto array_return;
378cc40b 700 case O_SPLIT:
a687059c 701 value = str_gnum(st[3]);
702 sp = do_split(str, arg[2].arg_ptr.arg_spat, (int)value,
703 gimme,arglast);
704 goto array_return;
378cc40b 705 case O_LENGTH:
a687059c 706 if (maxarg < 1)
707 value = (double)str_len(stab_val(defstab));
708 else
709 value = (double)str_len(st[1]);
378cc40b 710 goto donumset;
711 case O_SPRINTF:
a687059c 712 do_sprintf(str, sp-arglast[0], st+1);
378cc40b 713 break;
714 case O_SUBSTR:
a687059c 715 anum = ((int)str_gnum(st[2])) - arybase; /* anum=where to start*/
716 tmps = str_get(st[1]); /* force conversion to string */
717 if (argtype = (str == st[1]))
718 str = arg->arg_ptr.arg_str;
719 if (anum < 0)
720 anum += st[1]->str_cur + arybase;
721 if (anum < 0 || anum > st[1]->str_cur)
722 str_nset(str,"",0);
723 else {
724 optype = (int)str_gnum(st[3]);
725 if (optype < 0)
726 optype = 0;
727 tmps += anum;
728 anum = st[1]->str_cur - anum; /* anum=how many bytes left*/
729 if (anum > optype)
730 anum = optype;
378cc40b 731 str_nset(str, tmps, anum);
a687059c 732 if (argtype) { /* it's an lvalue! */
733 lstr = (struct lstring*)str;
734 str->str_magic = st[1];
735 st[1]->str_rare = 's';
736 lstr->lstr_offset = tmps - str_get(st[1]);
737 lstr->lstr_len = anum;
738 }
739 }
740 break;
741 case O_PACK:
742 (void)do_pack(str,arglast);
378cc40b 743 break;
a687059c 744 case O_GREP:
745 sp = do_grep(arg,str,gimme,arglast);
746 goto array_return;
378cc40b 747 case O_JOIN:
a687059c 748 do_join(str,arglast);
378cc40b 749 break;
750 case O_SLT:
a687059c 751 tmps = str_get(st[1]);
752 value = (double) (str_cmp(st[1],st[2]) < 0);
378cc40b 753 goto donumset;
754 case O_SGT:
a687059c 755 tmps = str_get(st[1]);
756 value = (double) (str_cmp(st[1],st[2]) > 0);
378cc40b 757 goto donumset;
758 case O_SLE:
a687059c 759 tmps = str_get(st[1]);
760 value = (double) (str_cmp(st[1],st[2]) <= 0);
378cc40b 761 goto donumset;
762 case O_SGE:
a687059c 763 tmps = str_get(st[1]);
764 value = (double) (str_cmp(st[1],st[2]) >= 0);
378cc40b 765 goto donumset;
766 case O_SEQ:
a687059c 767 tmps = str_get(st[1]);
768 value = (double) str_eq(st[1],st[2]);
378cc40b 769 goto donumset;
770 case O_SNE:
a687059c 771 tmps = str_get(st[1]);
772 value = (double) !str_eq(st[1],st[2]);
378cc40b 773 goto donumset;
774 case O_SUBR:
a687059c 775 sp = do_subr(arg,gimme,arglast);
776 st = stack->ary_array + arglast[0]; /* maybe realloced */
777 goto array_return;
778 case O_DBSUBR:
779 sp = do_dbsubr(arg,gimme,arglast);
780 st = stack->ary_array + arglast[0]; /* maybe realloced */
781 goto array_return;
378cc40b 782 case O_SORT:
a687059c 783 if ((arg[1].arg_type & A_MASK) == A_WORD)
784 stab = arg[1].arg_ptr.arg_stab;
785 else
786 stab = stabent(str_get(st[1]),TRUE);
787 if (!stab)
378cc40b 788 stab = defoutstab;
a687059c 789 sp = do_sort(str,stab,
790 gimme,arglast);
791 goto array_return;
792 case O_REVERSE:
793 sp = do_reverse(str,
794 gimme,arglast);
795 goto array_return;
796 case O_WARN:
797 if (arglast[2] - arglast[1] != 1) {
798 do_join(str,arglast);
799 tmps = str_get(st[1]);
800 }
378cc40b 801 else {
a687059c 802 str = st[2];
803 tmps = str_get(st[2]);
378cc40b 804 }
a687059c 805 if (!tmps || !*tmps)
806 tmps = "Warning: something's wrong";
807 warn("%s",tmps);
808 goto say_yes;
809 case O_DIE:
810 if (arglast[2] - arglast[1] != 1) {
811 do_join(str,arglast);
812 tmps = str_get(st[1]);
378cc40b 813 }
a687059c 814 else {
815 str = st[2];
816 tmps = str_get(st[2]);
817 }
818 if (!tmps || !*tmps)
819 exit(1);
820 fatal("%s",tmps);
821 goto say_zero;
378cc40b 822 case O_PRTF:
823 case O_PRINT:
a687059c 824 if ((arg[1].arg_type & A_MASK) == A_WORD)
825 stab = arg[1].arg_ptr.arg_stab;
826 else
827 stab = stabent(str_get(st[1]),TRUE);
828 if (!stab)
378cc40b 829 stab = defoutstab;
a687059c 830 if (!stab_io(stab)) {
831 if (dowarn)
832 warn("Filehandle never opened");
833 goto say_zero;
834 }
835 if (!(fp = stab_io(stab)->ofp)) {
836 if (dowarn) {
837 if (stab_io(stab)->ifp)
838 warn("Filehandle opened only for input");
839 else
840 warn("Print on closed filehandle");
841 }
842 goto say_zero;
378cc40b 843 }
378cc40b 844 else {
a687059c 845 if (optype == O_PRTF || arglast[2] - arglast[1] != 1)
846 value = (double)do_aprint(arg,fp,arglast);
378cc40b 847 else {
a687059c 848 value = (double)do_print(st[2],fp);
849 if (orslen && optype == O_PRINT)
850 if (fwrite(ors, 1, orslen, fp) == 0)
851 goto say_zero;
378cc40b 852 }
a687059c 853 if (stab_io(stab)->flags & IOF_FLUSH)
854 if (fflush(fp) == EOF)
855 goto say_zero;
378cc40b 856 }
857 goto donumset;
858 case O_CHDIR:
a687059c 859 if (maxarg < 1)
afd9f252 860 tmps = Nullch;
a687059c 861 else
862 tmps = str_get(st[1]);
863 if (!tmps || !*tmps) {
864 tmpstr = hfetch(stab_hash(envstab),"HOME",4,FALSE);
865 if (tmpstr)
866 tmps = str_get(tmpstr);
867 }
868 if (!tmps || !*tmps) {
869 tmpstr = hfetch(stab_hash(envstab),"LOGDIR",6,FALSE);
870 if (tmpstr)
871 tmps = str_get(tmpstr);
872 }
873#ifdef TAINT
874 taintproper("Insecure dependency in chdir");
875#endif
378cc40b 876 value = (double)(chdir(tmps) >= 0);
877 goto donumset;
378cc40b 878 case O_EXIT:
a687059c 879 if (maxarg < 1)
880 anum = 0;
881 else
882 anum = (int)str_gnum(st[1]);
883 exit(anum);
884 goto say_zero;
378cc40b 885 case O_RESET:
a687059c 886 if (maxarg < 1)
887 tmps = "";
888 else
889 tmps = str_get(st[1]);
890 str_reset(tmps,arg[2].arg_ptr.arg_hash);
378cc40b 891 value = 1.0;
892 goto donumset;
893 case O_LIST:
a687059c 894 if (gimme == G_ARRAY)
895 goto array_return;
378cc40b 896 if (maxarg > 0)
a687059c 897 str = st[sp - arglast[0]]; /* unwanted list, return last item */
378cc40b 898 else
a687059c 899 str = &str_undef;
378cc40b 900 break;
901 case O_EOF:
902 if (maxarg <= 0)
903 stab = last_in_stab;
a687059c 904 else if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 905 stab = arg[1].arg_ptr.arg_stab;
906 else
a687059c 907 stab = stabent(str_get(st[1]),TRUE);
378cc40b 908 str_set(str, do_eof(stab) ? Yes : No);
909 STABSET(str);
910 break;
a687059c 911 case O_GETC:
378cc40b 912 if (maxarg <= 0)
a687059c 913 stab = stdinstab;
914 else if ((arg[1].arg_type & A_MASK) == A_WORD)
378cc40b 915 stab = arg[1].arg_ptr.arg_stab;
916 else
a687059c 917 stab = stabent(str_get(st[1]),TRUE);
918 if (do_eof(stab)) /* make sure we have fp with something */
919 str_set(str, No);
920 else {
921#ifdef TAINT
922 tainted = 1;
923#endif
924 str_set(str," ");
925 *str->str_ptr = getc(stab_io(stab)->ifp); /* should never be EOF */
926 }
927 STABSET(str);
928 break;
929 case O_TELL:
930 if (maxarg <= 0)
931 stab = last_in_stab;
932 else if ((arg[1].arg_type & A_MASK) == A_WORD)
933 stab = arg[1].arg_ptr.arg_stab;
934 else
935 stab = stabent(str_get(st[1]),TRUE);
936#ifndef lint
937 value = (double)do_tell(stab);
938#else
939 (void)do_tell(stab);
940#endif
941 goto donumset;
942 case O_RECV:
943 case O_READ:
944 if ((arg[1].arg_type & A_MASK) == A_WORD)
945 stab = arg[1].arg_ptr.arg_stab;
946 else
947 stab = stabent(str_get(st[1]),TRUE);
948 tmps = str_get(st[2]);
949 anum = (int)str_gnum(st[3]);
950 STR_GROW(st[2], anum+1), (tmps = str_get(st[2])); /* sneaky */
951 errno = 0;
952 if (!stab_io(stab) || !stab_io(stab)->ifp)
953 goto say_zero;
954#ifdef SOCKET
955 else if (optype == O_RECV) {
956 argtype = sizeof buf;
957 optype = (int)str_gnum(st[4]);
958 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, optype,
959 buf, &argtype);
960 if (anum >= 0) {
961 st[2]->str_cur = anum;
962 st[2]->str_ptr[anum] = '\0';
963 str_nset(str,buf,argtype);
964 }
965 else
966 str_sset(str,&str_undef);
967 break;
968 }
969 else if (stab_io(stab)->type == 's') {
970 argtype = sizeof buf;
971 anum = recvfrom(fileno(stab_io(stab)->ifp), tmps, anum, 0,
972 buf, &argtype);
973 }
974#else
975 else if (optype == O_RECV)
976 goto badsock;
977#endif
978 else
979 anum = fread(tmps, 1, anum, stab_io(stab)->ifp);
980 if (anum < 0)
981 goto say_undef;
982 st[2]->str_cur = anum;
983 st[2]->str_ptr[anum] = '\0';
984 value = (double)anum;
985 goto donumset;
986 case O_SEND:
987#ifdef SOCKET
988 if ((arg[1].arg_type & A_MASK) == A_WORD)
989 stab = arg[1].arg_ptr.arg_stab;
990 else
991 stab = stabent(str_get(st[1]),TRUE);
992 tmps = str_get(st[2]);
993 anum = (int)str_gnum(st[3]);
994 optype = sp - arglast[0];
995 errno = 0;
996 if (optype > 4)
997 warn("Too many args on send");
663a0e37 998 stio = stab_io(stab);
999 if (!stio || !stio->ifp) {
1000 anum = -1;
1001 if (dowarn)
1002 warn("Send on closed socket");
1003 }
1004 else if (optype >= 4) {
a687059c 1005 tmps2 = str_get(st[4]);
1006 anum = sendto(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur,
1007 anum, tmps2, st[4]->str_cur);
1008 }
1009 else
1010 anum = send(fileno(stab_io(stab)->ifp), tmps, st[2]->str_cur, anum);
1011 if (anum < 0)
1012 goto say_undef;
1013 value = (double)anum;
1014 goto donumset;
1015#else
1016 goto badsock;
1017#endif
1018 case O_SEEK:
1019 if ((arg[1].arg_type & A_MASK) == A_WORD)
1020 stab = arg[1].arg_ptr.arg_stab;
378cc40b 1021 else
a687059c 1022 stab = stabent(str_get(st[1]),TRUE);
1023 value = str_gnum(st[2]);
378cc40b 1024 str_set(str, do_seek(stab,
a687059c 1025 (long)value, (int)str_gnum(st[3]) ) ? Yes : No);
378cc40b 1026 STABSET(str);
1027 break;
a687059c 1028 case O_RETURN:
afd9f252 1029 tmps = "_SUB_"; /* just fake up a "last _SUB_" */
a687059c 1030 optype = O_LAST;
afd9f252 1031 if (wantarray == G_ARRAY) {
a687059c 1032 lastretstr = Nullstr;
1033 lastspbase = arglast[1];
1034 lastsize = arglast[2] - arglast[1];
1035 }
1036 else
1037 lastretstr = str_static(st[arglast[2] - arglast[0]]);
1038 goto dopop;
378cc40b 1039 case O_REDO:
1040 case O_NEXT:
1041 case O_LAST:
1042 if (maxarg > 0) {
a687059c 1043 tmps = str_get(arg[1].arg_ptr.arg_str);
1044 dopop:
378cc40b 1045 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
1046 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
1047#ifdef DEBUGGING
1048 if (debug & 4) {
1049 deb("(Skipping label #%d %s)\n",loop_ptr,
1050 loop_stack[loop_ptr].loop_label);
1051 }
1052#endif
1053 loop_ptr--;
1054 }
1055#ifdef DEBUGGING
1056 if (debug & 4) {
1057 deb("(Found label #%d %s)\n",loop_ptr,
1058 loop_stack[loop_ptr].loop_label);
1059 }
1060#endif
1061 }
1062 if (loop_ptr < 0)
1063 fatal("Bad label: %s", maxarg > 0 ? tmps : "<null>");
a687059c 1064 if (!lastretstr && optype == O_LAST && lastsize) {
1065 st -= arglast[0];
1066 st += lastspbase + 1;
1067 optype = loop_stack[loop_ptr].loop_sp - lastspbase; /* negative */
1068 if (optype) {
1069 for (anum = lastsize; anum > 0; anum--,st++)
1070 st[optype] = str_static(st[0]);
1071 }
1072 longjmp(loop_stack[loop_ptr].loop_env, O_LAST);
1073 }
378cc40b 1074 longjmp(loop_stack[loop_ptr].loop_env, optype);
a687059c 1075 case O_DUMP:
378cc40b 1076 case O_GOTO:/* shudder */
a687059c 1077 goto_targ = str_get(arg[1].arg_ptr.arg_str);
1078 if (!*goto_targ)
1079 goto_targ = Nullch; /* just restart from top */
1080 if (optype == O_DUMP) {
1081 do_undump = 1;
1082 abort();
1083 }
378cc40b 1084 longjmp(top_env, 1);
1085 case O_INDEX:
a687059c 1086 tmps = str_get(st[1]);
1087#ifndef lint
1088 if (!(tmps2 = fbminstr((unsigned char*)tmps,
1089 (unsigned char*)tmps + st[1]->str_cur, st[2])))
1090#else
1091 if (tmps2 = fbminstr(Null(unsigned char*),Null(unsigned char*),Nullstr))
1092#endif
1093 value = (double)(-1 + arybase);
1094 else
1095 value = (double)(tmps2 - tmps + arybase);
1096 goto donumset;
1097 case O_RINDEX:
1098 tmps = str_get(st[1]);
1099 tmps2 = str_get(st[2]);
1100#ifndef lint
1101 if (!(tmps2 = rninstr(tmps, tmps + st[1]->str_cur,
1102 tmps2, tmps2 + st[2]->str_cur)))
1103#else
1104 if (tmps2 = rninstr(Nullch,Nullch,Nullch,Nullch))
1105#endif
378cc40b 1106 value = (double)(-1 + arybase);
1107 else
1108 value = (double)(tmps2 - tmps + arybase);
1109 goto donumset;
1110 case O_TIME:
a687059c 1111#ifndef lint
378cc40b 1112 value = (double) time(Null(long*));
a687059c 1113#endif
378cc40b 1114 goto donumset;
1115 case O_TMS:
a687059c 1116 sp = do_tms(str,gimme,arglast);
1117 goto array_return;
378cc40b 1118 case O_LOCALTIME:
a687059c 1119 if (maxarg < 1)
1120 (void)time(&when);
1121 else
1122 when = (long)str_gnum(st[1]);
1123 sp = do_time(str,localtime(&when),
1124 gimme,arglast);
1125 goto array_return;
378cc40b 1126 case O_GMTIME:
a687059c 1127 if (maxarg < 1)
1128 (void)time(&when);
1129 else
1130 when = (long)str_gnum(st[1]);
1131 sp = do_time(str,gmtime(&when),
1132 gimme,arglast);
1133 goto array_return;
1134 case O_LSTAT:
378cc40b 1135 case O_STAT:
a687059c 1136 sp = do_stat(str,arg,
1137 gimme,arglast);
1138 goto array_return;
378cc40b 1139 case O_CRYPT:
1140#ifdef CRYPT
a687059c 1141 tmps = str_get(st[1]);
1142#ifdef FCRYPT
1143 str_set(str,fcrypt(tmps,str_get(st[2])));
1144#else
1145 str_set(str,crypt(tmps,str_get(st[2])));
1146#endif
378cc40b 1147#else
1148 fatal(
1149 "The crypt() function is unimplemented due to excessive paranoia.");
1150#endif
1151 break;
a687059c 1152 case O_ATAN2:
1153 value = str_gnum(st[1]);
1154 value = atan2(value,str_gnum(st[2]));
1155 goto donumset;
1156 case O_SIN:
1157 if (maxarg < 1)
1158 value = str_gnum(stab_val(defstab));
1159 else
1160 value = str_gnum(st[1]);
1161 value = sin(value);
1162 goto donumset;
1163 case O_COS:
1164 if (maxarg < 1)
1165 value = str_gnum(stab_val(defstab));
1166 else
1167 value = str_gnum(st[1]);
1168 value = cos(value);
1169 goto donumset;
1170 case O_RAND:
1171 if (maxarg < 1)
1172 value = 1.0;
1173 else
1174 value = str_gnum(st[1]);
1175 if (value == 0.0)
1176 value = 1.0;
1177#if RANDBITS == 31
1178 value = rand() * value / 2147483648.0;
1179#else
1180#if RANDBITS == 16
1181 value = rand() * value / 65536.0;
1182#else
1183#if RANDBITS == 15
1184 value = rand() * value / 32768.0;
1185#else
1186 value = rand() * value / (double)(((unsigned long)1) << RANDBITS);
1187#endif
1188#endif
1189#endif
1190 goto donumset;
1191 case O_SRAND:
1192 if (maxarg < 1) {
1193 (void)time(&when);
1194 anum = when;
1195 }
1196 else
1197 anum = (int)str_gnum(st[1]);
1198 (void)srand(anum);
1199 goto say_yes;
378cc40b 1200 case O_EXP:
a687059c 1201 if (maxarg < 1)
1202 value = str_gnum(stab_val(defstab));
1203 else
1204 value = str_gnum(st[1]);
1205 value = exp(value);
378cc40b 1206 goto donumset;
1207 case O_LOG:
a687059c 1208 if (maxarg < 1)
1209 value = str_gnum(stab_val(defstab));
1210 else
1211 value = str_gnum(st[1]);
1212 value = log(value);
378cc40b 1213 goto donumset;
1214 case O_SQRT:
a687059c 1215 if (maxarg < 1)
1216 value = str_gnum(stab_val(defstab));
1217 else
1218 value = str_gnum(st[1]);
1219 value = sqrt(value);
378cc40b 1220 goto donumset;
1221 case O_INT:
a687059c 1222 if (maxarg < 1)
1223 value = str_gnum(stab_val(defstab));
1224 else
1225 value = str_gnum(st[1]);
378cc40b 1226 if (value >= 0.0)
a687059c 1227 (void)modf(value,&value);
378cc40b 1228 else {
a687059c 1229 (void)modf(-value,&value);
378cc40b 1230 value = -value;
1231 }
1232 goto donumset;
1233 case O_ORD:
a687059c 1234 if (maxarg < 1)
1235 tmps = str_get(stab_val(defstab));
1236 else
1237 tmps = str_get(st[1]);
1238#ifndef I286
663a0e37 1239 value = (double) (*tmps & 255);
a687059c 1240#else
1241 anum = (int) *tmps;
663a0e37 1242 value = (double) (anum & 255);
a687059c 1243#endif
378cc40b 1244 goto donumset;
1245 case O_SLEEP:
a687059c 1246 if (maxarg < 1)
1247 tmps = Nullch;
1248 else
1249 tmps = str_get(st[1]);
1250 (void)time(&when);
378cc40b 1251 if (!tmps || !*tmps)
1252 sleep((32767<<16)+32767);
1253 else
a687059c 1254 sleep((unsigned int)atoi(tmps));
1255#ifndef lint
378cc40b 1256 value = (double)when;
a687059c 1257 (void)time(&when);
378cc40b 1258 value = ((double)when) - value;
a687059c 1259#endif
378cc40b 1260 goto donumset;
a687059c 1261 case O_RANGE:
1262 sp = do_range(gimme,arglast);
1263 goto array_return;
1264 case O_F_OR_R:
1265 if (gimme == G_ARRAY) { /* it's a range */
1266 /* can we optimize to constant array? */
1267 if ((arg[1].arg_type & A_MASK) == A_SINGLE &&
1268 (arg[2].arg_type & A_MASK) == A_SINGLE) {
1269 st[2] = arg[2].arg_ptr.arg_str;
1270 sp = do_range(gimme,arglast);
1271 st = stack->ary_array;
1272 maxarg = sp - arglast[0];
1273 str_free(arg[1].arg_ptr.arg_str);
1274 str_free(arg[2].arg_ptr.arg_str);
1275 arg->arg_type = O_ARRAY;
1276 arg[1].arg_type = A_STAB|A_DONT;
1277 arg->arg_len = 1;
1278 stab = arg[1].arg_ptr.arg_stab = aadd(genstab());
1279 ary = stab_array(stab);
1280 afill(ary,maxarg - 1);
1281 st += arglast[0]+1;
1282 while (maxarg-- > 0)
1283 ary->ary_array[maxarg] = str_smake(st[maxarg]);
1284 goto array_return;
1285 }
1286 arg->arg_type = optype = O_RANGE;
1287 maxarg = arg->arg_len = 2;
1288 anum = 2;
1289 arg[anum].arg_flags &= ~AF_ARYOK;
1290 argflags = arg[anum].arg_flags;
1291 argtype = arg[anum].arg_type & A_MASK;
1292 arg[anum].arg_type = argtype;
1293 argptr = arg[anum].arg_ptr;
1294 sp = arglast[0];
1295 st -= sp;
1296 sp++;
1297 goto re_eval;
1298 }
1299 arg->arg_type = O_FLIP;
1300 /* FALL THROUGH */
378cc40b 1301 case O_FLIP:
a687059c 1302 if ((arg[1].arg_type & A_MASK) == A_SINGLE ?
1303 last_in_stab && (int)str_gnum(st[1]) == stab_io(last_in_stab)->lines
1304 :
1305 str_true(st[1]) ) {
378cc40b 1306 str_numset(str,0.0);
1307 anum = 2;
1308 arg->arg_type = optype = O_FLOP;
a687059c 1309 arg[2].arg_type &= ~A_DONT;
1310 arg[1].arg_type |= A_DONT;
378cc40b 1311 argflags = arg[2].arg_flags;
a687059c 1312 argtype = arg[2].arg_type & A_MASK;
378cc40b 1313 argptr = arg[2].arg_ptr;
a687059c 1314 sp = arglast[0];
1315 st -= sp;
378cc40b 1316 goto re_eval;
1317 }
1318 str_set(str,"");
1319 break;
1320 case O_FLOP:
1321 str_inc(str);
a687059c 1322 if ((arg[2].arg_type & A_MASK) == A_SINGLE ?
1323 last_in_stab && (int)str_gnum(st[2]) == stab_io(last_in_stab)->lines
1324 :
1325 str_true(st[2]) ) {
378cc40b 1326 arg->arg_type = O_FLIP;
a687059c 1327 arg[1].arg_type &= ~A_DONT;
1328 arg[2].arg_type |= A_DONT;
378cc40b 1329 str_cat(str,"E0");
1330 }
1331 break;
1332 case O_FORK:
a687059c 1333 anum = fork();
1334 if (!anum && (tmpstab = stabent("$",allstabs)))
1335 str_numset(STAB_STR(tmpstab),(double)getpid());
1336 value = (double)anum;
378cc40b 1337 goto donumset;
1338 case O_WAIT:
a687059c 1339#ifndef lint
afd9f252 1340 /* ihand = signal(SIGINT, SIG_IGN); */
1341 /* qhand = signal(SIGQUIT, SIG_IGN); */
a687059c 1342 anum = wait(&argflags);
1343 if (anum > 0)
1344 pidgone(anum,argflags);
1345 value = (double)anum;
1346#else
afd9f252 1347 /* ihand = qhand = 0; */
a687059c 1348#endif
afd9f252 1349 /* (void)signal(SIGINT, ihand); */
1350 /* (void)signal(SIGQUIT, qhand); */
378cc40b 1351 statusvalue = (unsigned short)argflags;
1352 goto donumset;
1353 case O_SYSTEM:
a687059c 1354#ifdef TAINT
1355 if (arglast[2] - arglast[1] == 1) {
1356 taintenv();
1357 tainted |= st[2]->str_tainted;
1358 taintproper("Insecure dependency in system");
1359 }
1360#endif
378cc40b 1361 while ((anum = vfork()) == -1) {
1362 if (errno != EAGAIN) {
1363 value = -1.0;
1364 goto donumset;
1365 }
1366 sleep(5);
1367 }
1368 if (anum > 0) {
a687059c 1369#ifndef lint
378cc40b 1370 ihand = signal(SIGINT, SIG_IGN);
1371 qhand = signal(SIGQUIT, SIG_IGN);
a687059c 1372 while ((argtype = wait(&argflags)) != anum && argtype >= 0)
1373 pidgone(argtype,argflags);
1374#else
1375 ihand = qhand = 0;
1376#endif
1377 (void)signal(SIGINT, ihand);
1378 (void)signal(SIGQUIT, qhand);
378cc40b 1379 statusvalue = (unsigned short)argflags;
1380 if (argtype == -1)
1381 value = -1.0;
1382 else {
1383 value = (double)((unsigned int)argflags & 0xffff);
1384 }
1385 goto donumset;
1386 }
a687059c 1387 if ((arg[1].arg_type & A_MASK) == A_STAB)
1388 value = (double)do_aexec(st[1],arglast);
1389 else if (arglast[2] - arglast[1] != 1)
1390 value = (double)do_aexec(Nullstr,arglast);
378cc40b 1391 else {
a687059c 1392 value = (double)do_exec(str_get(str_static(st[2])));
378cc40b 1393 }
1394 _exit(-1);
1395 case O_EXEC:
a687059c 1396 if ((arg[1].arg_type & A_MASK) == A_STAB)
1397 value = (double)do_aexec(st[1],arglast);
1398 else if (arglast[2] - arglast[1] != 1)
1399 value = (double)do_aexec(Nullstr,arglast);
378cc40b 1400 else {
a687059c 1401 value = (double)do_exec(str_get(str_static(st[2])));
378cc40b 1402 }
1403 goto donumset;
1404 case O_HEX:
1405 argtype = 4;
1406 goto snarfnum;
1407
1408 case O_OCT:
1409 argtype = 3;
1410
1411 snarfnum:
1412 anum = 0;
a687059c 1413 if (maxarg < 1)
1414 tmps = str_get(stab_val(defstab));
1415 else
1416 tmps = str_get(st[1]);
378cc40b 1417 for (;;) {
1418 switch (*tmps) {
1419 default:
1420 goto out;
1421 case '8': case '9':
1422 if (argtype != 4)
1423 goto out;
1424 /* FALL THROUGH */
1425 case '0': case '1': case '2': case '3': case '4':
1426 case '5': case '6': case '7':
1427 anum <<= argtype;
1428 anum += *tmps++ & 15;
1429 break;
1430 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1431 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1432 if (argtype != 4)
1433 goto out;
1434 anum <<= 4;
1435 anum += (*tmps++ & 7) + 9;
1436 break;
1437 case 'x':
1438 argtype = 4;
1439 tmps++;
1440 break;
1441 }
1442 }
1443 out:
1444 value = (double)anum;
1445 goto donumset;
1446 case O_CHMOD:
1447 case O_CHOWN:
1448 case O_KILL:
1449 case O_UNLINK:
1450 case O_UTIME:
a687059c 1451 value = (double)apply(optype,arglast);
378cc40b 1452 goto donumset;
1453 case O_UMASK:
a687059c 1454 if (maxarg < 1) {
1455 anum = umask(0);
1456 (void)umask(anum);
1457 }
1458 else
1459 anum = umask((int)str_gnum(st[1]));
1460 value = (double)anum;
1461#ifdef TAINT
1462 taintproper("Insecure dependency in umask");
1463#endif
378cc40b 1464 goto donumset;
1465 case O_RENAME:
a687059c 1466 tmps = str_get(st[1]);
1467 tmps2 = str_get(st[2]);
1468#ifdef TAINT
1469 taintproper("Insecure dependency in rename");
1470#endif
378cc40b 1471#ifdef RENAME
a687059c 1472 value = (double)(rename(tmps,tmps2) >= 0);
378cc40b 1473#else
378cc40b 1474 if (euid || stat(tmps2,&statbuf) < 0 ||
1475 (statbuf.st_mode & S_IFMT) != S_IFDIR )
a687059c 1476 (void)UNLINK(tmps2); /* avoid unlinking a directory */
378cc40b 1477 if (!(anum = link(tmps,tmps2)))
1478 anum = UNLINK(tmps);
1479 value = (double)(anum >= 0);
1480#endif
1481 goto donumset;
1482 case O_LINK:
a687059c 1483 tmps = str_get(st[1]);
1484 tmps2 = str_get(st[2]);
1485#ifdef TAINT
1486 taintproper("Insecure dependency in link");
1487#endif
1488 value = (double)(link(tmps,tmps2) >= 0);
1489 goto donumset;
1490 case O_MKDIR:
1491 tmps = str_get(st[1]);
1492 anum = (int)str_gnum(st[2]);
1493#ifdef TAINT
1494 taintproper("Insecure dependency in mkdir");
1495#endif
1496#ifdef MKDIR
1497 value = (double)(mkdir(tmps,anum) >= 0);
bf38876a 1498 goto donumset;
a687059c 1499#else
bf38876a 1500 (void)strcpy(buf,"mkdir ");
1501#endif
1502#if !defined(MKDIR) || !defined(RMDIR)
a687059c 1503 one_liner:
bf38876a 1504 for (tmps2 = buf+6; *tmps; ) {
1505 *tmps2++ = '\\';
1506 *tmps2++ = *tmps++;
1507 }
1508 (void)strcpy(tmps2," 2>&1");
a687059c 1509 rsfp = mypopen(buf,"r");
1510 if (rsfp) {
1511 *buf = '\0';
1512 tmps2 = fgets(buf,sizeof buf,rsfp);
1513 (void)mypclose(rsfp);
1514 if (tmps2 != Nullch) {
bf38876a 1515 for (errno = 1; errno < sys_nerr; errno++) {
a687059c 1516 if (instr(buf,sys_errlist[errno])) /* you don't see this */
1517 goto say_zero;
1518 }
1519 errno = 0;
bf38876a 1520#ifndef EACCES
1521#define EACCES EPERM
1522#endif
1523 if (instr(buf,"cannot make"))
1524 errno = EEXIST;
1525 else if (instr(buf,"non-exist"))
1526 errno = ENOENT;
afd9f252 1527 else if (instr(buf,"does not exist"))
1528 errno = ENOENT;
bf38876a 1529 else if (instr(buf,"not empty"))
1530 errno = EBUSY;
1531 else if (instr(buf,"cannot access"))
1532 errno = EACCES;
1533 else
1534 errno = EPERM;
a687059c 1535 goto say_zero;
1536 }
bf38876a 1537 else { /* some mkdirs return no failure indication */
1538 tmps = str_get(st[1]);
1539 anum = (stat(tmps,&statbuf) >= 0);
1540 if (optype == O_RMDIR)
1541 anum = !anum;
1542 if (anum)
1543 errno = 0;
1544 else
1545 errno = EACCES; /* a guess */
1546 value = (double)anum;
1547 }
1548 goto donumset;
a687059c 1549 }
1550 else
1551 goto say_zero;
1552#endif
a687059c 1553 case O_RMDIR:
1554 if (maxarg < 1)
1555 tmps = str_get(stab_val(defstab));
1556 else
1557 tmps = str_get(st[1]);
1558#ifdef TAINT
1559 taintproper("Insecure dependency in rmdir");
1560#endif
1561#ifdef RMDIR
1562 value = (double)(rmdir(tmps) >= 0);
1563 goto donumset;
1564#else
bf38876a 1565 (void)strcpy(buf,"rmdir ");
a687059c 1566 goto one_liner; /* see above in MKDIR */
1567#endif
1568 case O_GETPPID:
1569 value = (double)getppid();
1570 goto donumset;
1571 case O_GETPGRP:
1572#ifdef GETPGRP
1573 if (maxarg < 1)
1574 anum = 0;
1575 else
1576 anum = (int)str_gnum(st[1]);
1577 value = (double)getpgrp(anum);
1578 goto donumset;
1579#else
1580 fatal("The getpgrp() function is unimplemented on this machine");
1581 break;
1582#endif
1583 case O_SETPGRP:
1584#ifdef SETPGRP
1585 argtype = (int)str_gnum(st[1]);
1586 anum = (int)str_gnum(st[2]);
1587#ifdef TAINT
1588 taintproper("Insecure dependency in setpgrp");
1589#endif
1590 value = (double)(setpgrp(argtype,anum) >= 0);
1591 goto donumset;
1592#else
1593 fatal("The setpgrp() function is unimplemented on this machine");
1594 break;
1595#endif
1596 case O_GETPRIORITY:
1597#ifdef GETPRIORITY
1598 argtype = (int)str_gnum(st[1]);
1599 anum = (int)str_gnum(st[2]);
1600 value = (double)getpriority(argtype,anum);
1601 goto donumset;
1602#else
1603 fatal("The getpriority() function is unimplemented on this machine");
1604 break;
1605#endif
1606 case O_SETPRIORITY:
1607#ifdef SETPRIORITY
1608 argtype = (int)str_gnum(st[1]);
1609 anum = (int)str_gnum(st[2]);
1610 optype = (int)str_gnum(st[3]);
1611#ifdef TAINT
1612 taintproper("Insecure dependency in setpriority");
1613#endif
1614 value = (double)(setpriority(argtype,anum,optype) >= 0);
378cc40b 1615 goto donumset;
a687059c 1616#else
1617 fatal("The setpriority() function is unimplemented on this machine");
1618 break;
1619#endif
1620 case O_CHROOT:
1621 if (maxarg < 1)
1622 tmps = str_get(stab_val(defstab));
1623 else
1624 tmps = str_get(st[1]);
1625#ifdef TAINT
1626 taintproper("Insecure dependency in chroot");
1627#endif
1628 value = (double)(chroot(tmps) >= 0);
1629 goto donumset;
1630 case O_FCNTL:
1631 case O_IOCTL:
1632 if (maxarg <= 0)
1633 stab = last_in_stab;
1634 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1635 stab = arg[1].arg_ptr.arg_stab;
1636 else
1637 stab = stabent(str_get(st[1]),TRUE);
afd9f252 1638 argtype = (unsigned int)str_gnum(st[2]);
a687059c 1639#ifdef TAINT
1640 taintproper("Insecure dependency in ioctl");
1641#endif
1642 anum = do_ctl(optype,stab,argtype,st[3]);
1643 if (anum == -1)
1644 goto say_undef;
1645 if (anum != 0)
1646 goto donumset;
1647 str_set(str,"0 but true");
1648 STABSET(str);
1649 break;
1650 case O_FLOCK:
1651#ifdef FLOCK
1652 if (maxarg <= 0)
1653 stab = last_in_stab;
1654 else if ((arg[1].arg_type & A_MASK) == A_WORD)
1655 stab = arg[1].arg_ptr.arg_stab;
1656 else
1657 stab = stabent(str_get(st[1]),TRUE);
1658 if (stab && stab_io(stab))
1659 fp = stab_io(stab)->ifp;
1660 else
1661 fp = Nullfp;
1662 if (fp) {
1663 argtype = (int)str_gnum(st[2]);
1664 value = (double)(flock(fileno(fp),argtype) >= 0);
1665 }
1666 else
1667 value = 0;
1668 goto donumset;
1669#else
1670 fatal("The flock() function is unimplemented on this machine");
1671 break;
1672#endif
378cc40b 1673 case O_UNSHIFT:
a687059c 1674 ary = stab_array(arg[1].arg_ptr.arg_stab);
1675 if (arglast[2] - arglast[1] != 1)
1676 do_unshift(ary,arglast);
378cc40b 1677 else {
a687059c 1678 str = Str_new(52,0); /* must copy the STR */
1679 str_sset(str,st[2]);
378cc40b 1680 aunshift(ary,1);
a687059c 1681 (void)astore(ary,0,str);
378cc40b 1682 }
1683 value = (double)(ary->ary_fill + 1);
1684 break;
1685 case O_DOFILE:
1686 case O_EVAL:
a687059c 1687 if (maxarg < 1)
1688 tmpstr = stab_val(defstab);
1689 else
1690 tmpstr =
1691 (arg[1].arg_type & A_MASK) != A_NULL ? st[1] : stab_val(defstab);
1692#ifdef TAINT
1693 tainted |= tmpstr->str_tainted;
1694 taintproper("Insecure dependency in eval");
1695#endif
1696 sp = do_eval(tmpstr, optype, arg[2].arg_ptr.arg_hash,
1697 gimme,arglast);
1698 goto array_return;
378cc40b 1699
1700 case O_FTRREAD:
1701 argtype = 0;
1702 anum = S_IREAD;
1703 goto check_perm;
1704 case O_FTRWRITE:
1705 argtype = 0;
1706 anum = S_IWRITE;
1707 goto check_perm;
1708 case O_FTREXEC:
1709 argtype = 0;
1710 anum = S_IEXEC;
1711 goto check_perm;
1712 case O_FTEREAD:
1713 argtype = 1;
1714 anum = S_IREAD;
1715 goto check_perm;
1716 case O_FTEWRITE:
1717 argtype = 1;
1718 anum = S_IWRITE;
1719 goto check_perm;
1720 case O_FTEEXEC:
1721 argtype = 1;
1722 anum = S_IEXEC;
1723 check_perm:
a687059c 1724 if (mystat(arg,st[1]) < 0)
1725 goto say_undef;
1726 if (cando(anum,argtype,&statcache))
1727 goto say_yes;
1728 goto say_no;
378cc40b 1729
1730 case O_FTIS:
a687059c 1731 if (mystat(arg,st[1]) < 0)
1732 goto say_undef;
1733 goto say_yes;
378cc40b 1734 case O_FTEOWNED:
1735 case O_FTROWNED:
a687059c 1736 if (mystat(arg,st[1]) < 0)
1737 goto say_undef;
1738 if (statcache.st_uid == (optype == O_FTEOWNED ? euid : uid) )
1739 goto say_yes;
1740 goto say_no;
378cc40b 1741 case O_FTZERO:
a687059c 1742 if (mystat(arg,st[1]) < 0)
1743 goto say_undef;
1744 if (!statcache.st_size)
1745 goto say_yes;
1746 goto say_no;
378cc40b 1747 case O_FTSIZE:
a687059c 1748 if (mystat(arg,st[1]) < 0)
1749 goto say_undef;
1750 if (statcache.st_size)
1751 goto say_yes;
1752 goto say_no;
378cc40b 1753
1754 case O_FTSOCK:
1755#ifdef S_IFSOCK
1756 anum = S_IFSOCK;
1757 goto check_file_type;
1758#else
a687059c 1759 goto say_no;
378cc40b 1760#endif
1761 case O_FTCHR:
1762 anum = S_IFCHR;
1763 goto check_file_type;
1764 case O_FTBLK:
1765 anum = S_IFBLK;
1766 goto check_file_type;
1767 case O_FTFILE:
1768 anum = S_IFREG;
1769 goto check_file_type;
1770 case O_FTDIR:
1771 anum = S_IFDIR;
1772 check_file_type:
a687059c 1773 if (mystat(arg,st[1]) < 0)
1774 goto say_undef;
1775 if ((statcache.st_mode & S_IFMT) == anum )
1776 goto say_yes;
1777 goto say_no;
378cc40b 1778 case O_FTPIPE:
1779#ifdef S_IFIFO
1780 anum = S_IFIFO;
1781 goto check_file_type;
1782#else
a687059c 1783 goto say_no;
378cc40b 1784#endif
1785 case O_FTLINK:
afd9f252 1786 if (arg[1].arg_type & A_DONT)
1787 fatal("You must supply explicit filename with -l");
0d3e774c 1788#ifdef LSTAT
a687059c 1789 if (lstat(str_get(st[1]),&statcache) < 0)
1790 goto say_undef;
1791 if ((statcache.st_mode & S_IFMT) == S_IFLNK )
1792 goto say_yes;
378cc40b 1793#endif
a687059c 1794 goto say_no;
378cc40b 1795 case O_SYMLINK:
1796#ifdef SYMLINK
a687059c 1797 tmps = str_get(st[1]);
1798 tmps2 = str_get(st[2]);
1799#ifdef TAINT
1800 taintproper("Insecure dependency in symlink");
1801#endif
1802 value = (double)(symlink(tmps,tmps2) >= 0);
378cc40b 1803 goto donumset;
1804#else
1805 fatal("Unsupported function symlink()");
1806#endif
a687059c 1807 case O_READLINK:
1808#ifdef SYMLINK
1809 if (maxarg < 1)
1810 tmps = str_get(stab_val(defstab));
1811 else
1812 tmps = str_get(st[1]);
1813 anum = readlink(tmps,buf,sizeof buf);
1814 if (anum < 0)
1815 goto say_undef;
1816 str_nset(str,buf,anum);
1817 break;
1818#else
1819 fatal("Unsupported function readlink()");
1820#endif
378cc40b 1821 case O_FTSUID:
1822 anum = S_ISUID;
1823 goto check_xid;
1824 case O_FTSGID:
1825 anum = S_ISGID;
1826 goto check_xid;
1827 case O_FTSVTX:
1828 anum = S_ISVTX;
1829 check_xid:
a687059c 1830 if (mystat(arg,st[1]) < 0)
1831 goto say_undef;
1832 if (statcache.st_mode & anum)
1833 goto say_yes;
1834 goto say_no;
378cc40b 1835 case O_FTTTY:
a687059c 1836 if (arg[1].arg_type & A_DONT) {
378cc40b 1837 stab = arg[1].arg_ptr.arg_stab;
1838 tmps = "";
1839 }
1840 else
a687059c 1841 stab = stabent(tmps = str_get(st[1]),FALSE);
1842 if (stab && stab_io(stab) && stab_io(stab)->ifp)
1843 anum = fileno(stab_io(stab)->ifp);
378cc40b 1844 else if (isdigit(*tmps))
1845 anum = atoi(tmps);
1846 else
a687059c 1847 goto say_undef;
378cc40b 1848 if (isatty(anum))
a687059c 1849 goto say_yes;
1850 goto say_no;
378cc40b 1851 case O_FTTEXT:
1852 case O_FTBINARY:
a687059c 1853 str = do_fttext(arg,st[1]);
378cc40b 1854 break;
a687059c 1855#ifdef SOCKET
1856 case O_SOCKET:
1857 if ((arg[1].arg_type & A_MASK) == A_WORD)
1858 stab = arg[1].arg_ptr.arg_stab;
1859 else
1860 stab = stabent(str_get(st[1]),TRUE);
1861#ifndef lint
1862 value = (double)do_socket(stab,arglast);
1863#else
1864 (void)do_socket(stab,arglast);
1865#endif
1866 goto donumset;
1867 case O_BIND:
1868 if ((arg[1].arg_type & A_MASK) == A_WORD)
1869 stab = arg[1].arg_ptr.arg_stab;
1870 else
1871 stab = stabent(str_get(st[1]),TRUE);
1872#ifndef lint
1873 value = (double)do_bind(stab,arglast);
1874#else
1875 (void)do_bind(stab,arglast);
1876#endif
1877 goto donumset;
1878 case O_CONNECT:
1879 if ((arg[1].arg_type & A_MASK) == A_WORD)
1880 stab = arg[1].arg_ptr.arg_stab;
1881 else
1882 stab = stabent(str_get(st[1]),TRUE);
1883#ifndef lint
1884 value = (double)do_connect(stab,arglast);
1885#else
1886 (void)do_connect(stab,arglast);
1887#endif
1888 goto donumset;
1889 case O_LISTEN:
1890 if ((arg[1].arg_type & A_MASK) == A_WORD)
1891 stab = arg[1].arg_ptr.arg_stab;
1892 else
1893 stab = stabent(str_get(st[1]),TRUE);
1894#ifndef lint
1895 value = (double)do_listen(stab,arglast);
1896#else
1897 (void)do_listen(stab,arglast);
1898#endif
1899 goto donumset;
1900 case O_ACCEPT:
1901 if ((arg[1].arg_type & A_MASK) == A_WORD)
1902 stab = arg[1].arg_ptr.arg_stab;
1903 else
1904 stab = stabent(str_get(st[1]),TRUE);
1905 if ((arg[2].arg_type & A_MASK) == A_WORD)
1906 stab2 = arg[2].arg_ptr.arg_stab;
1907 else
1908 stab2 = stabent(str_get(st[2]),TRUE);
1909 do_accept(str,stab,stab2);
1910 STABSET(str);
1911 break;
1912 case O_GHBYNAME:
1913 if (maxarg < 1)
1914 goto say_undef;
1915 case O_GHBYADDR:
1916 case O_GHOSTENT:
1917 sp = do_ghent(optype,
1918 gimme,arglast);
1919 goto array_return;
1920 case O_GNBYNAME:
1921 if (maxarg < 1)
1922 goto say_undef;
1923 case O_GNBYADDR:
1924 case O_GNETENT:
1925 sp = do_gnent(optype,
1926 gimme,arglast);
1927 goto array_return;
1928 case O_GPBYNAME:
1929 if (maxarg < 1)
1930 goto say_undef;
1931 case O_GPBYNUMBER:
1932 case O_GPROTOENT:
1933 sp = do_gpent(optype,
1934 gimme,arglast);
1935 goto array_return;
1936 case O_GSBYNAME:
1937 if (maxarg < 1)
1938 goto say_undef;
1939 case O_GSBYPORT:
1940 case O_GSERVENT:
1941 sp = do_gsent(optype,
1942 gimme,arglast);
1943 goto array_return;
1944 case O_SHOSTENT:
1945 value = (double) sethostent((int)str_gnum(st[1]));
1946 goto donumset;
1947 case O_SNETENT:
1948 value = (double) setnetent((int)str_gnum(st[1]));
1949 goto donumset;
1950 case O_SPROTOENT:
1951 value = (double) setprotoent((int)str_gnum(st[1]));
1952 goto donumset;
1953 case O_SSERVENT:
1954 value = (double) setservent((int)str_gnum(st[1]));
1955 goto donumset;
1956 case O_EHOSTENT:
1957 value = (double) endhostent();
1958 goto donumset;
1959 case O_ENETENT:
1960 value = (double) endnetent();
1961 goto donumset;
1962 case O_EPROTOENT:
1963 value = (double) endprotoent();
1964 goto donumset;
1965 case O_ESERVENT:
1966 value = (double) endservent();
1967 goto donumset;
1968 case O_SSELECT:
1969 sp = do_select(gimme,arglast);
1970 goto array_return;
1971 case O_SOCKETPAIR:
1972 if ((arg[1].arg_type & A_MASK) == A_WORD)
1973 stab = arg[1].arg_ptr.arg_stab;
1974 else
1975 stab = stabent(str_get(st[1]),TRUE);
1976 if ((arg[2].arg_type & A_MASK) == A_WORD)
1977 stab2 = arg[2].arg_ptr.arg_stab;
1978 else
1979 stab2 = stabent(str_get(st[2]),TRUE);
1980#ifndef lint
1981 value = (double)do_spair(stab,stab2,arglast);
1982#else
1983 (void)do_spair(stab,stab2,arglast);
1984#endif
1985 goto donumset;
1986 case O_SHUTDOWN:
1987 if ((arg[1].arg_type & A_MASK) == A_WORD)
1988 stab = arg[1].arg_ptr.arg_stab;
1989 else
1990 stab = stabent(str_get(st[1]),TRUE);
1991#ifndef lint
1992 value = (double)do_shutdown(stab,arglast);
1993#else
1994 (void)do_shutdown(stab,arglast);
1995#endif
1996 goto donumset;
1997 case O_GSOCKOPT:
1998 case O_SSOCKOPT:
1999 if ((arg[1].arg_type & A_MASK) == A_WORD)
2000 stab = arg[1].arg_ptr.arg_stab;
2001 else
2002 stab = stabent(str_get(st[1]),TRUE);
2003 sp = do_sopt(optype,stab,arglast);
2004 goto array_return;
2005 case O_GETSOCKNAME:
2006 case O_GETPEERNAME:
2007 if ((arg[1].arg_type & A_MASK) == A_WORD)
2008 stab = arg[1].arg_ptr.arg_stab;
2009 else
2010 stab = stabent(str_get(st[1]),TRUE);
2011 sp = do_getsockname(optype,stab,arglast);
2012 goto array_return;
2013
2014#else /* SOCKET not defined */
2015 case O_SOCKET:
2016 case O_BIND:
2017 case O_CONNECT:
2018 case O_LISTEN:
2019 case O_ACCEPT:
2020 case O_SSELECT:
2021 case O_SOCKETPAIR:
2022 case O_GHBYNAME:
2023 case O_GHBYADDR:
2024 case O_GHOSTENT:
2025 case O_GNBYNAME:
2026 case O_GNBYADDR:
2027 case O_GNETENT:
2028 case O_GPBYNAME:
2029 case O_GPBYNUMBER:
2030 case O_GPROTOENT:
2031 case O_GSBYNAME:
2032 case O_GSBYPORT:
2033 case O_GSERVENT:
2034 case O_SHOSTENT:
2035 case O_SNETENT:
2036 case O_SPROTOENT:
2037 case O_SSERVENT:
2038 case O_EHOSTENT:
2039 case O_ENETENT:
2040 case O_EPROTOENT:
2041 case O_ESERVENT:
2042 case O_SHUTDOWN:
2043 case O_GSOCKOPT:
2044 case O_SSOCKOPT:
2045 case O_GETSOCKNAME:
2046 case O_GETPEERNAME:
2047 badsock:
2048 fatal("Unsupported socket function");
2049#endif /* SOCKET */
2050 case O_FILENO:
bf38876a 2051 if (maxarg < 1)
2052 goto say_undef;
a687059c 2053 if ((arg[1].arg_type & A_MASK) == A_WORD)
2054 stab = arg[1].arg_ptr.arg_stab;
2055 else
2056 stab = stabent(str_get(st[1]),TRUE);
2057 if (!stab || !(stio = stab_io(stab)) || !(fp = stio->ifp))
2058 goto say_undef;
2059 value = fileno(fp);
2060 goto donumset;
2061 case O_VEC:
2062 sp = do_vec(str == st[1], arg->arg_ptr.arg_str, arglast);
2063 goto array_return;
2064 case O_GPWNAM:
2065 case O_GPWUID:
2066 case O_GPWENT:
2067 sp = do_gpwent(optype,
2068 gimme,arglast);
2069 goto array_return;
2070 case O_SPWENT:
2071 value = (double) setpwent();
2072 goto donumset;
2073 case O_EPWENT:
2074 value = (double) endpwent();
2075 goto donumset;
2076 case O_GGRNAM:
2077 case O_GGRGID:
2078 case O_GGRENT:
2079 sp = do_ggrent(optype,
2080 gimme,arglast);
2081 goto array_return;
2082 case O_SGRENT:
2083 value = (double) setgrent();
2084 goto donumset;
2085 case O_EGRENT:
2086 value = (double) endgrent();
2087 goto donumset;
2088 case O_GETLOGIN:
2089 if (!(tmps = getlogin()))
2090 goto say_undef;
2091 str_set(str,tmps);
2092 break;
2093 case O_OPENDIR:
2094 case O_READDIR:
2095 case O_TELLDIR:
2096 case O_SEEKDIR:
2097 case O_REWINDDIR:
2098 case O_CLOSEDIR:
bf38876a 2099 if (maxarg < 1)
2100 goto say_undef;
a687059c 2101 if ((arg[1].arg_type & A_MASK) == A_WORD)
2102 stab = arg[1].arg_ptr.arg_stab;
2103 else
2104 stab = stabent(str_get(st[1]),TRUE);
2105 sp = do_dirop(optype,stab,gimme,arglast);
2106 goto array_return;
2107 case O_SYSCALL:
2108 value = (double)do_syscall(arglast);
2109 goto donumset;
afd9f252 2110 case O_PIPE:
2111 if ((arg[1].arg_type & A_MASK) == A_WORD)
2112 stab = arg[1].arg_ptr.arg_stab;
2113 else
2114 stab = stabent(str_get(st[1]),TRUE);
2115 if ((arg[2].arg_type & A_MASK) == A_WORD)
2116 stab2 = arg[2].arg_ptr.arg_stab;
2117 else
2118 stab2 = stabent(str_get(st[2]),TRUE);
2119 do_pipe(str,stab,stab2);
2120 STABSET(str);
2121 break;
378cc40b 2122 }
a687059c 2123
2124 normal_return:
2125 st[1] = str;
378cc40b 2126#ifdef DEBUGGING
2127 if (debug) {
2128 dlevel--;
2129 if (debug & 8)
2130 deb("%s RETURNS \"%s\"\n",opname[optype],str_get(str));
2131 }
2132#endif
a687059c 2133 return arglast[0] + 1;
378cc40b 2134
2135array_return:
2136#ifdef DEBUGGING
2137 if (debug) {
2138 dlevel--;
afd9f252 2139 if (debug & 8) {
2140 anum = sp - arglast[0];
2141 switch (anum) {
2142 case 0:
2143 deb("%s RETURNS ()\n",opname[optype]);
2144 break;
2145 case 1:
2146 deb("%s RETURNS (\"%s\")\n",opname[optype],str_get(st[1]));
2147 break;
2148 default:
2149 deb("%s RETURNS %d ARGS (\"%s\",%s\"%s\"\n",opname[optype],anum,
2150 str_get(st[1]),anum==2?"":"...,",str_get(st[anum]));
2151 break;
2152 }
2153 }
378cc40b 2154 }
2155#endif
a687059c 2156 return sp;
2157
2158say_yes:
2159 str = &str_yes;
2160 goto normal_return;
2161
2162say_no:
2163 str = &str_no;
2164 goto normal_return;
2165
2166say_undef:
2167 str = &str_undef;
2168 goto normal_return;
2169
2170say_zero:
2171 value = 0.0;
2172 /* FALL THROUGH */
378cc40b 2173
2174donumset:
2175 str_numset(str,value);
2176 STABSET(str);
a687059c 2177 st[1] = str;
378cc40b 2178#ifdef DEBUGGING
2179 if (debug) {
2180 dlevel--;
2181 if (debug & 8)
2182 deb("%s RETURNS \"%f\"\n",opname[optype],value);
2183 }
2184#endif
a687059c 2185 return arglast[0] + 1;
378cc40b 2186}