home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume20 / perl3.0 / part03 < prev    next >
Encoding:
Internet Message Format  |  1989-10-29  |  50.3 KB

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