home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / perl / part32 < prev    next >
Internet Message Format  |  1991-04-20  |  51KB

  1. From: lwall@netlabs.com (Larry Wall)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i050:  perl - The perl programming language, Part32/36
  4. Message-ID: <1991Apr19.014918.4993@sparky.IMD.Sterling.COM>
  5. Date: 19 Apr 91 01:49:18 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 44efcec8 d0e9bce7 d23c186a 78357a51
  8.  
  9. Submitted-by: Larry Wall <lwall@netlabs.com>
  10. Posting-number: Volume 18, Issue 50
  11. Archive-name: perl/part32
  12.  
  13. [There are 36 kits for perl version 4.0.]
  14.  
  15. #! /bin/sh
  16.  
  17. # Make a new directory for the perl sources, cd to it, and run kits 1
  18. # thru 36 through sh.  When all 36 kits have been run, read README.
  19.  
  20. echo "This is perl 4.0 kit 32 (of 36).  If kit 32 is complete, the line"
  21. echo '"'"End of kit 32 (of 36)"'" will echo at the end.'
  22. echo ""
  23. export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
  24. mkdir lib msdos t t/cmd t/op usub 2>/dev/null
  25. echo Extracting msdos/directory.c
  26. sed >msdos/directory.c <<'!STUFFY!FUNK!' -e 's/X//'
  27. X/* $Header: directory.c,v 4.0 91/03/20 01:34:24 lwall Locked $
  28. X *
  29. X *    (C) Copyright 1987, 1988, 1990 Diomidis Spinellis.
  30. X *
  31. X *    You may distribute under the terms of the GNU General Public License
  32. X *    as specified in the README file that comes with the perl 3.0 kit.
  33. X *
  34. X * $Log:    directory.c,v $
  35. X * Revision 4.0  91/03/20  01:34:24  lwall
  36. X * 4.0 baseline.
  37. X * 
  38. X * Revision 3.0.1.1  90/03/27  16:07:37  lwall
  39. X * patch16: MSDOS support
  40. X * 
  41. X * Revision 1.3  90/03/16  22:39:40  dds
  42. X * Fixed malloc problem.
  43. X *
  44. X * Revision 1.2  88/07/23  00:08:39  dds
  45. X * Added inode non-zero filling.
  46. X *
  47. X * Revision 1.1  88/07/23  00:03:50  dds
  48. X * Initial revision
  49. X *
  50. X */
  51. X
  52. X/*
  53. X * UNIX compatible directory access functions
  54. X */
  55. X
  56. X#include <sys/types.h>
  57. X#include <sys/dir.h>
  58. X#include <stddef.h>
  59. X#include <stdlib.h>
  60. X#include <string.h>
  61. X#include <dos.h>
  62. X#include <ctype.h>
  63. X
  64. X/*
  65. X * File names are converted to lowercase if the
  66. X * CONVERT_TO_LOWER_CASE variable is defined.
  67. X */
  68. X#define CONVERT_TO_LOWER_CASE
  69. X
  70. X#define PATHLEN 65
  71. X
  72. X#ifndef lint
  73. Xstatic char rcsid[] = "$Header: directory.c,v 4.0 91/03/20 01:34:24 lwall Locked $";
  74. X#endif
  75. X
  76. XDIR *
  77. Xopendir(char *filename)
  78. X{
  79. X    DIR            *p;
  80. X    char           *oldresult, *result;
  81. X    union REGS      srv;
  82. X    struct SREGS    segregs;
  83. X    register        reslen = 0;
  84. X    char            scannamespc[PATHLEN];
  85. X    char        *scanname = scannamespc;    /* To take address we need a pointer */
  86. X
  87. X    /*
  88. X     * Structure used by the MS-DOS directory system calls.
  89. X     */
  90. X    struct dir_buff {
  91. X        char            reserved[21];    /* Reserved for MS-DOS */
  92. X        unsigned char   attribute;    /* Attribute */
  93. X        unsigned int    time;        /* Time */
  94. X        unsigned int    date;        /* Date */
  95. X        long            size;        /* Size of file */
  96. X        char            fn[13];        /* Filename */
  97. X    } buffspc, *buff = &buffspc;
  98. X
  99. X
  100. X    if (!(p = (DIR *) malloc(sizeof(DIR))))
  101. X        return NULL;
  102. X
  103. X    /* Initialize result to use realloc on it */
  104. X    if (!(result = malloc(1))) {
  105. X        free(p);
  106. X        return NULL;
  107. X    }
  108. X
  109. X    /* Create the search pattern */
  110. X    strcpy(scanname, filename);
  111. X    if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
  112. X        strcat(scanname, "/*.*");
  113. X    else
  114. X        strcat(scanname, "*.*");
  115. X
  116. X    segread(&segregs);
  117. X#if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  118. X    segregs.ds = FP_SEG(buff);
  119. X    srv.x.dx = FP_OFF(buff);
  120. X#else
  121. X    srv.x.dx = (unsigned int) buff;
  122. X#endif
  123. X    srv.h.ah = 0x1a;    /* Set DTA to DS:DX */
  124. X    intdosx(&srv, &srv, &segregs);
  125. X
  126. X#if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  127. X    segregs.ds = FP_SEG(scanname);
  128. X    srv.x.dx = FP_OFF(scanname);
  129. X#else
  130. X    srv.x.dx = (unsigned int) scanname;
  131. X#endif
  132. X    srv.x.cx = 0xff;    /* Search mode */
  133. X
  134. X    for (srv.h.ah = 0x4e; !intdosx(&srv, &srv, &segregs); srv.h.ah = 0x4f) {
  135. X        if ((result = (char *) realloc(result, reslen + strlen(buff->fn) + 1)) ==
  136. X NULL) {
  137. X            free(p);
  138. X            free(oldresult);
  139. X            return NULL;
  140. X        }
  141. X        oldresult = result;
  142. X#ifdef CONVERT_TO_LOWER_CASE
  143. X        strcpy(result + reslen, strlwr(buff->fn));
  144. X#else
  145. X        strcpy(result + reslen, buff->fn);
  146. X#endif
  147. X        reslen += strlen(buff->fn) + 1;
  148. X    }
  149. X
  150. X    if (!(result = realloc(result, reslen + 1))) {
  151. X        free(p);
  152. X        free(oldresult);
  153. X        return NULL;
  154. X    } else {
  155. X        p->start = result;
  156. X        p->curr = result;
  157. X        *(result + reslen) = '\0';
  158. X        return p;
  159. X    }
  160. X}
  161. X
  162. X
  163. Xstruct direct  *
  164. Xreaddir(DIR *dirp)
  165. X{
  166. X    char           *p;
  167. X    register        len;
  168. X    static          dummy;
  169. X
  170. X    p = dirp->curr;
  171. X    len = strlen(p);
  172. X    if (*p) {
  173. X        dirp->curr += len + 1;
  174. X        strcpy(dirp->dirstr.d_name, p);
  175. X        dirp->dirstr.d_namlen = len;
  176. X        /* To fool programs */
  177. X        dirp->dirstr.d_ino = ++dummy;
  178. X        return &(dirp->dirstr);
  179. X    } else
  180. X        return NULL;
  181. X}
  182. X
  183. Xlong
  184. Xtelldir(DIR *dirp)
  185. X{
  186. X    return (long) dirp->curr;    /* ouch! pointer to long cast */
  187. X}
  188. X
  189. Xvoid
  190. Xseekdir(DIR *dirp, long loc)
  191. X{
  192. X    dirp->curr = (char *) loc;    /* ouch! long to pointer cast */
  193. X}
  194. X
  195. Xvoid
  196. Xrewinddir(DIR *dirp)
  197. X{
  198. X    dirp->curr = dirp->start;
  199. X}
  200. X
  201. Xvoid
  202. Xclosedir(DIR *dirp)
  203. X{
  204. X    free(dirp->start);
  205. X    free(dirp);
  206. X}
  207. !STUFFY!FUNK!
  208. echo Extracting ioctl.pl
  209. sed >ioctl.pl <<'!STUFFY!FUNK!' -e 's/X//'
  210. X$TIOCGSIZE = 0x40087468;
  211. X$TIOCSSIZE = 0x80087467;
  212. X$IOCPARM_MASK = 0x1fff;
  213. X$IOCPARM_MAX = 0x200;
  214. X$IOC_VOID = 0x20000000;
  215. X$IOC_OUT = 0x40000000;
  216. X$IOC_IN = 0x80000000;
  217. X$IOC_INOUT = 0xC0000000;
  218. X$IOC_DIRMASK = 0xe0000000;
  219. X$TIOCGETD = 0x40047400;
  220. X$TIOCSETD = 0x80047401;
  221. X$TIOCHPCL = 0x20007402;
  222. X$TIOCMODG = 0x40047403;
  223. X$TIOCMODS = 0x80047404;
  224. X$TIOCM_LE = 0001;
  225. X$TIOCM_DTR = 0002;
  226. X$TIOCM_RTS = 0004;
  227. X$TIOCM_ST = 0010;
  228. X$TIOCM_SR = 0020;
  229. X$TIOCM_CTS = 0040;
  230. X$TIOCM_CAR = 0100;
  231. X$TIOCM_CD = 0x40;
  232. X$TIOCM_RNG = 0200;
  233. X$TIOCM_RI = 0x80;
  234. X$TIOCM_DSR = 0400;
  235. X$TIOCGETP = 0x40067408;
  236. X$TIOCSETP = 0x80067409;
  237. X$TIOCSETN = 0x8006740A;
  238. X$TIOCEXCL = 0x2000740D;
  239. X$TIOCNXCL = 0x2000740E;
  240. X$TIOCFLUSH = 0x80047410;
  241. X$TIOCSETC = 0x80067411;
  242. X$TIOCGETC = 0x40067412;
  243. X$TANDEM = 0x00000001;
  244. X$CBREAK = 0x00000002;
  245. X$LCASE = 0x00000004;
  246. X$ECHO = 0x00000008;
  247. X$CRMOD = 0x00000010;
  248. X$RAW = 0x00000020;
  249. X$ODDP = 0x00000040;
  250. X$EVENP = 0x00000080;
  251. X$ANYP = 0x000000c0;
  252. X$NLDELAY = 0x00000300;
  253. X$NL0 = 0x00000000;
  254. X$NL1 = 0x00000100;
  255. X$NL2 = 0x00000200;
  256. X$NL3 = 0x00000300;
  257. X$TBDELAY = 0x00000c00;
  258. X$TAB0 = 0x00000000;
  259. X$TAB1 = 0x00000400;
  260. X$TAB2 = 0x00000800;
  261. X$XTABS = 0x00000c00;
  262. X$CRDELAY = 0x00003000;
  263. X$CR0 = 0x00000000;
  264. X$CR1 = 0x00001000;
  265. X$CR2 = 0x00002000;
  266. X$CR3 = 0x00003000;
  267. X$VTDELAY = 0x00004000;
  268. X$FF0 = 0x00000000;
  269. X$FF1 = 0x00004000;
  270. X$BSDELAY = 0x00008000;
  271. X$BS0 = 0x00000000;
  272. X$BS1 = 0x00008000;
  273. X$ALLDELAY = 0xFF00;
  274. X$CRTBS = 0x00010000;
  275. X$PRTERA = 0x00020000;
  276. X$CRTERA = 0x00040000;
  277. X$TILDE = 0x00080000;
  278. X$MDMBUF = 0x00100000;
  279. X$LITOUT = 0x00200000;
  280. X$TOSTOP = 0x00400000;
  281. X$FLUSHO = 0x00800000;
  282. X$NOHANG = 0x01000000;
  283. X$L001000 = 0x02000000;
  284. X$CRTKIL = 0x04000000;
  285. X$PASS8 = 0x08000000;
  286. X$CTLECH = 0x10000000;
  287. X$PENDIN = 0x20000000;
  288. X$DECCTQ = 0x40000000;
  289. X$NOFLSH = 0x80000000;
  290. X$TIOCLBIS = 0x8004747F;
  291. X$TIOCLBIC = 0x8004747E;
  292. X$TIOCLSET = 0x8004747D;
  293. X$TIOCLGET = 0x4004747C;
  294. X$LCRTBS = 0x1;
  295. X$LPRTERA = 0x2;
  296. X$LCRTERA = 0x4;
  297. X$LTILDE = 0x8;
  298. X$LMDMBUF = 0x10;
  299. X$LLITOUT = 0x20;
  300. X$LTOSTOP = 0x40;
  301. X$LFLUSHO = 0x80;
  302. X$LNOHANG = 0x100;
  303. X$LCRTKIL = 0x400;
  304. X$LPASS8 = 0x800;
  305. X$LCTLECH = 0x1000;
  306. X$LPENDIN = 0x2000;
  307. X$LDECCTQ = 0x4000;
  308. X$LNOFLSH = 0xFFFF8000;
  309. X$TIOCSBRK = 0x2000747B;
  310. X$TIOCCBRK = 0x2000747A;
  311. X$TIOCSDTR = 0x20007479;
  312. X$TIOCCDTR = 0x20007478;
  313. X$TIOCGPGRP = 0x40047477;
  314. X$TIOCSPGRP = 0x80047476;
  315. X$TIOCSLTC = 0x80067475;
  316. X$TIOCGLTC = 0x40067474;
  317. X$TIOCOUTQ = 0x40047473;
  318. X$TIOCSTI = 0x80017472;
  319. X$TIOCNOTTY = 0x20007471;
  320. X$TIOCPKT = 0x80047470;
  321. X$TIOCPKT_DATA = 0x00;
  322. X$TIOCPKT_FLUSHREAD = 0x01;
  323. X$TIOCPKT_FLUSHWRITE = 0x02;
  324. X$TIOCPKT_STOP = 0x04;
  325. X$TIOCPKT_START = 0x08;
  326. X$TIOCPKT_NOSTOP = 0x10;
  327. X$TIOCPKT_DOSTOP = 0x20;
  328. X$TIOCSTOP = 0x2000746F;
  329. X$TIOCSTART = 0x2000746E;
  330. X$TIOCMSET = 0x8004746D;
  331. X$TIOCMBIS = 0x8004746C;
  332. X$TIOCMBIC = 0x8004746B;
  333. X$TIOCMGET = 0x4004746A;
  334. X$TIOCREMOTE = 0x80047469;
  335. X$TIOCGWINSZ = 0x40087468;
  336. X$TIOCSWINSZ = 0x80087467;
  337. X$TIOCUCNTL = 0x80047466;
  338. X$TIOCSSOFTC = 0x80047465;
  339. X$TIOCGSOFTC = 0x40047464;
  340. X$TIOCSCARR = 0x80047463;
  341. X$TIOCWCARR = 0x20007462;
  342. X$OTTYDISC = 0;
  343. X$NETLDISC = 1;
  344. X$NTTYDISC = 2;
  345. X$TABLDISC = 3;
  346. X$SLIPDISC = 4;
  347. X$FIOCLEX = 0x20006601;
  348. X$FIONCLEX = 0x20006602;
  349. X$FIONREAD = 0x4004667F;
  350. X$FIONBIO = 0x8004667E;
  351. X$FIOASYNC = 0x8004667D;
  352. X$FIOSETOWN = 0x8004667C;
  353. X$FIOGETOWN = 0x4004667B;
  354. X$SIOCSHIWAT = 0x80047300;
  355. X$SIOCGHIWAT = 0x40047301;
  356. X$SIOCSLOWAT = 0x80047302;
  357. X$SIOCGLOWAT = 0x40047303;
  358. X$SIOCATMARK = 0x40047307;
  359. X$SIOCSPGRP = 0x80047308;
  360. X$SIOCGPGRP = 0x40047309;
  361. X$SIOCADDRT = 0x8030720A;
  362. X$SIOCDELRT = 0x8030720B;
  363. X$SIOCSIFADDR = 0x8020690C;
  364. X$SIOCGIFADDR = 0xC020690D;
  365. X$SIOCSIFDSTADDR = 0x8020690E;
  366. X$SIOCGIFDSTADDR = 0xC020690F;
  367. X$SIOCSIFFLAGS = 0x80206910;
  368. X$SIOCGIFFLAGS = 0xC0206911;
  369. X$SIOCGIFBRDADDR = 0xC0206912;
  370. X$SIOCSIFBRDADDR = 0x80206913;
  371. X$SIOCGIFCONF = 0xC0086914;
  372. X$SIOCGIFNETMASK = 0xC0206915;
  373. X$SIOCSIFNETMASK = 0x80206916;
  374. X$SIOCGIFMETRIC = 0xC0206917;
  375. X$SIOCSIFMETRIC = 0x80206918;
  376. X$SIOCSARP = 0x8024691E;
  377. X$SIOCGARP = 0xC024691F;
  378. X$SIOCDARP = 0x80246920;
  379. !STUFFY!FUNK!
  380. echo Extracting lib/validate.pl
  381. sed >lib/validate.pl <<'!STUFFY!FUNK!' -e 's/X//'
  382. X;# $Header: validate.pl,v 4.0 91/03/20 01:26:56 lwall Locked $
  383. X
  384. X;# The validate routine takes a single multiline string consisting of
  385. X;# lines containing a filename plus a file test to try on it.  (The
  386. X;# file test may also be a 'cd', causing subsequent relative filenames
  387. X;# to be interpreted relative to that directory.)  After the file test
  388. X;# you may put '|| die' to make it a fatal error if the file test fails.
  389. X;# The default is '|| warn'.  The file test may optionally have a ! prepended
  390. X;# to test for the opposite condition.  If you do a cd and then list some
  391. X;# relative filenames, you may want to indent them slightly for readability.
  392. X;# If you supply your own "die" or "warn" message, you can use $file to
  393. X;# interpolate the filename.
  394. X
  395. X;# Filetests may be bunched:  -rwx tests for all of -r, -w and -x.
  396. X;# Only the first failed test of the bunch will produce a warning.
  397. X
  398. X;# The routine returns the number of warnings issued.
  399. X
  400. X;# Usage:
  401. X;#    require "validate.pl";
  402. X;#    $warnings += do validate('
  403. X;#    /vmunix            -e || die
  404. X;#    /boot            -e || die
  405. X;#    /bin            cd
  406. X;#        csh            -ex
  407. X;#        csh            !-ug
  408. X;#        sh            -ex
  409. X;#        sh            !-ug
  410. X;#    /usr            -d || warn "What happened to $file?\n"
  411. X;#    ');
  412. X
  413. Xsub validate {
  414. X    local($file,$test,$warnings,$oldwarnings);
  415. X    foreach $check (split(/\n/,$_[0])) {
  416. X    next if $check =~ /^#/;
  417. X    next if $check =~ /^$/;
  418. X    ($file,$test) = split(' ',$check,2);
  419. X    if ($test =~ s/^(!?-)(\w{2,}\b)/$1Z/) {
  420. X        $testlist = $2;
  421. X        @testlist = split(//,$testlist);
  422. X    }
  423. X    else {
  424. X        @testlist = ('Z');
  425. X    }
  426. X    $oldwarnings = $warnings;
  427. X    foreach $one (@testlist) {
  428. X        $this = $test;
  429. X        $this =~ s/(-\w\b)/$1 \$file/g;
  430. X        $this =~ s/-Z/-$one/;
  431. X        $this .= ' || warn' unless $this =~ /\|\|/;
  432. X        $this =~ s/^(.*\S)\s*\|\|\s*(die|warn)$/$1 || do valmess('$2','$1')/;
  433. X        $this =~ s/\bcd\b/chdir (\$cwd = \$file)/g;
  434. X        eval $this;
  435. X        last if $warnings > $oldwarnings;
  436. X    }
  437. X    }
  438. X    $warnings;
  439. X}
  440. X
  441. Xsub valmess {
  442. X    local($disposition,$this) = @_;
  443. X    $file = $cwd . '/' . $file unless $file =~ m|^/|;
  444. X    if ($this =~ /^(!?)-(\w)\s+\$file\s*$/) {
  445. X    $neg = $1;
  446. X    $tmp = $2;
  447. X    $tmp eq 'r' && ($mess = "$file is not readable by uid $>.");
  448. X    $tmp eq 'w' && ($mess = "$file is not writable by uid $>.");
  449. X    $tmp eq 'x' && ($mess = "$file is not executable by uid $>.");
  450. X    $tmp eq 'o' && ($mess = "$file is not owned by uid $>.");
  451. X    $tmp eq 'R' && ($mess = "$file is not readable by you.");
  452. X    $tmp eq 'W' && ($mess = "$file is not writable by you.");
  453. X    $tmp eq 'X' && ($mess = "$file is not executable by you.");
  454. X    $tmp eq 'O' && ($mess = "$file is not owned by you.");
  455. X    $tmp eq 'e' && ($mess = "$file does not exist.");
  456. X    $tmp eq 'z' && ($mess = "$file does not have zero size.");
  457. X    $tmp eq 's' && ($mess = "$file does not have non-zero size.");
  458. X    $tmp eq 'f' && ($mess = "$file is not a plain file.");
  459. X    $tmp eq 'd' && ($mess = "$file is not a directory.");
  460. X    $tmp eq 'l' && ($mess = "$file is not a symbolic link.");
  461. X    $tmp eq 'p' && ($mess = "$file is not a named pipe (FIFO).");
  462. X    $tmp eq 'S' && ($mess = "$file is not a socket.");
  463. X    $tmp eq 'b' && ($mess = "$file is not a block special file.");
  464. X    $tmp eq 'c' && ($mess = "$file is not a character special file.");
  465. X    $tmp eq 'u' && ($mess = "$file does not have the setuid bit set.");
  466. X    $tmp eq 'g' && ($mess = "$file does not have the setgid bit set.");
  467. X    $tmp eq 'k' && ($mess = "$file does not have the sticky bit set.");
  468. X    $tmp eq 'T' && ($mess = "$file is not a text file.");
  469. X    $tmp eq 'B' && ($mess = "$file is not a binary file.");
  470. X    if ($neg eq '!') {
  471. X        $mess =~ s/ is not / should not be / ||
  472. X        $mess =~ s/ does not / should not / ||
  473. X        $mess =~ s/ not / /;
  474. X    }
  475. X    print stderr $mess,"\n";
  476. X    }
  477. X    else {
  478. X    $this =~ s/\$file/'$file'/g;
  479. X    print stderr "Can't do $this.\n";
  480. X    }
  481. X    if ($disposition eq 'die') { exit 1; }
  482. X    ++$warnings;
  483. X}
  484. X
  485. X1;
  486. !STUFFY!FUNK!
  487. echo Extracting stab.h
  488. sed >stab.h <<'!STUFFY!FUNK!' -e 's/X//'
  489. X/* $Header: stab.h,v 4.0 91/03/20 01:39:49 lwall Locked $
  490. X *
  491. X *    Copyright (c) 1989, Larry Wall
  492. X *
  493. X *    You may distribute under the terms of the GNU General Public License
  494. X *    as specified in the README file that comes with the perl 3.0 kit.
  495. X *
  496. X * $Log:    stab.h,v $
  497. X * Revision 4.0  91/03/20  01:39:49  lwall
  498. X * 4.0 baseline.
  499. X * 
  500. X */
  501. X
  502. Xstruct stabptrs {
  503. X    char        stbp_magic[4];
  504. X    STR        *stbp_val;    /* scalar value */
  505. X    struct stio *stbp_io;    /* filehandle value */
  506. X    FCMD    *stbp_form;    /* format value */
  507. X    ARRAY    *stbp_array;    /* array value */
  508. X    HASH    *stbp_hash;    /* associative array value */
  509. X    HASH    *stbp_stash;    /* symbol table for this stab */
  510. X    SUBR    *stbp_sub;    /* subroutine value */
  511. X    int        stbp_lastexpr;    /* used by nothing_in_common() */
  512. X    line_t    stbp_line;    /* line first declared at (for -w) */
  513. X    char    stbp_flags;
  514. X};
  515. X
  516. X#if defined(CRIPPLED_CC) && (defined(iAPX286) || defined(M_I286) || defined(I80286))
  517. X#define MICROPORT
  518. X#endif
  519. X
  520. X#define stab_magic(stab)    (((STBP*)(stab->str_ptr))->stbp_magic)
  521. X#define stab_val(stab)        (((STBP*)(stab->str_ptr))->stbp_val)
  522. X#define stab_io(stab)        (((STBP*)(stab->str_ptr))->stbp_io)
  523. X#define stab_form(stab)        (((STBP*)(stab->str_ptr))->stbp_form)
  524. X#define stab_xarray(stab)    (((STBP*)(stab->str_ptr))->stbp_array)
  525. X#ifdef    MICROPORT    /* Microport 2.4 hack */
  526. XARRAY *stab_array();
  527. X#else
  528. X#define stab_array(stab)    (((STBP*)(stab->str_ptr))->stbp_array ? \
  529. X                 ((STBP*)(stab->str_ptr))->stbp_array : \
  530. X                 ((STBP*)(aadd(stab)->str_ptr))->stbp_array)
  531. X#endif
  532. X#define stab_xhash(stab)    (((STBP*)(stab->str_ptr))->stbp_hash)
  533. X#ifdef    MICROPORT    /* Microport 2.4 hack */
  534. XHASH *stab_hash();
  535. X#else
  536. X#define stab_hash(stab)        (((STBP*)(stab->str_ptr))->stbp_hash ? \
  537. X                 ((STBP*)(stab->str_ptr))->stbp_hash : \
  538. X                 ((STBP*)(hadd(stab)->str_ptr))->stbp_hash)
  539. X#endif            /* Microport 2.4 hack */
  540. X#define stab_stash(stab)    (((STBP*)(stab->str_ptr))->stbp_stash)
  541. X#define stab_sub(stab)        (((STBP*)(stab->str_ptr))->stbp_sub)
  542. X#define stab_lastexpr(stab)    (((STBP*)(stab->str_ptr))->stbp_lastexpr)
  543. X#define stab_line(stab)        (((STBP*)(stab->str_ptr))->stbp_line)
  544. X#define stab_flags(stab)    (((STBP*)(stab->str_ptr))->stbp_flags)
  545. X#define stab_name(stab)        (stab->str_magic->str_ptr)
  546. X
  547. X#define SF_VMAGIC 1        /* call routine to dereference STR val */
  548. X#define SF_MULTI 2        /* seen more than once */
  549. X
  550. Xstruct stio {
  551. X    FILE    *ifp;        /* ifp and ofp are normally the same */
  552. X    FILE    *ofp;        /* but sockets need separate streams */
  553. X#ifdef HAS_READDIR
  554. X    DIR        *dirp;        /* for opendir, readdir, etc */
  555. X#endif
  556. X    long    lines;        /* $. */
  557. X    long    page;        /* $% */
  558. X    long    page_len;    /* $= */
  559. X    long    lines_left;    /* $- */
  560. X    char    *top_name;    /* $^ */
  561. X    STAB    *top_stab;    /* $^ */
  562. X    char    *fmt_name;    /* $~ */
  563. X    STAB    *fmt_stab;    /* $~ */
  564. X    short    subprocess;    /* -| or |- */
  565. X    char    type;
  566. X    char    flags;
  567. X};
  568. X
  569. X#define IOF_ARGV 1    /* this fp iterates over ARGV */
  570. X#define IOF_START 2    /* check for null ARGV and substitute '-' */
  571. X#define IOF_FLUSH 4    /* this fp wants a flush after write op */
  572. X
  573. Xstruct sub {
  574. X    CMD        *cmd;
  575. X    int        (*usersub)();
  576. X    int        userindex;
  577. X    STAB    *filestab;
  578. X    long    depth;    /* >= 2 indicates recursive call */
  579. X    ARRAY    *tosave;
  580. X};
  581. X
  582. X#define Nullstab Null(STAB*)
  583. X
  584. X#define STAB_STR(s) (tmpstab = (s), stab_flags(tmpstab) & SF_VMAGIC ? stab_str(stab_val(tmpstab)->str_magic) : stab_val(tmpstab))
  585. X#define STAB_GET(s) (tmpstab = (s), str_get(stab_flags(tmpstab) & SF_VMAGIC ? stab_str(tmpstab->str_magic) : stab_val(tmpstab)))
  586. X#define STAB_GNUM(s) (tmpstab = (s), str_gnum(stab_flags(tmpstab) & SF_VMAGIC ? stab_str(tmpstab->str_magic) : stab_val(tmpstab)))
  587. X
  588. XEXT STAB *tmpstab;
  589. X
  590. XEXT STAB *stab_index[128];
  591. X
  592. XEXT unsigned short statusvalue;
  593. X
  594. XEXT int delaymagic INIT(0);
  595. X#define DM_DELAY 1
  596. X#define DM_REUID 2
  597. X#define DM_REGID 4
  598. X
  599. XSTAB *aadd();
  600. XSTAB *hadd();
  601. XSTAB *fstab();
  602. !STUFFY!FUNK!
  603. echo Extracting usersub.c
  604. sed >usersub.c <<'!STUFFY!FUNK!' -e 's/X//'
  605. X/* $Header: usersub.c,v 4.0 91/03/20 01:55:56 lwall Locked $
  606. X *
  607. X *  This file contains stubs for routines that the user may define to
  608. X *  set up glue routines for C libraries or to decrypt encrypted scripts
  609. X *  for execution.
  610. X *
  611. X * $Log:    usersub.c,v $
  612. X * Revision 4.0  91/03/20  01:55:56  lwall
  613. X * 4.0 baseline.
  614. X * 
  615. X */
  616. X
  617. X#include "EXTERN.h"
  618. X#include "perl.h"
  619. X
  620. Xuserinit()
  621. X{
  622. X    return 0;
  623. X}
  624. X
  625. X/*
  626. X * The following is supplied by John MacDonald as a means of decrypting
  627. X * and executing (presumably proprietary) scripts that have been encrypted
  628. X * by a (presumably secret) method.  The idea is that you supply your own
  629. X * routine in place of cryptfilter (which is purposefully a very weak
  630. X * encryption).  If an encrypted script is detected, a process is forked
  631. X * off to run the cryptfilter routine as input to perl.
  632. X */
  633. X
  634. X#ifdef CRYPTSCRIPT
  635. X
  636. X#include <signal.h>
  637. X#ifdef I_VFORK
  638. X#include <vfork.h>
  639. X#endif
  640. X
  641. X#define    CRYPT_MAGIC_1    0xfb
  642. X#define    CRYPT_MAGIC_2    0xf1
  643. X
  644. Xcryptfilter( fil )
  645. XFILE *    fil;
  646. X{
  647. X    int    ch;
  648. X
  649. X    while( (ch = getc( fil )) != EOF ) {
  650. X    putchar( (ch ^ 0x80) );
  651. X    }
  652. X}
  653. X
  654. X#ifndef MSDOS
  655. Xstatic FILE    *lastpipefile;
  656. Xstatic int    pipepid;
  657. X
  658. X#ifdef VOIDSIG
  659. X#  define    VOID    void
  660. X#else
  661. X#  define    VOID    int
  662. X#endif
  663. X
  664. XFILE *
  665. Xmypfiopen(fil,func)        /* open a pipe to function call for input */
  666. XFILE    *fil;
  667. XVOID    (*func)();
  668. X{
  669. X    int p[2];
  670. X    STR *str;
  671. X
  672. X    if (pipe(p) < 0) {
  673. X    fclose( fil );
  674. X    fatal("Can't get pipe for decrypt");
  675. X    }
  676. X
  677. X    /* make sure that the child doesn't get anything extra */
  678. X    fflush(stdout);
  679. X    fflush(stderr);
  680. X
  681. X    while ((pipepid = fork()) < 0) {
  682. X    if (errno != EAGAIN) {
  683. X        close(p[0]);
  684. X        close(p[1]);
  685. X        fclose( fil );
  686. X        fatal("Can't fork for decrypt");
  687. X    }
  688. X    sleep(5);
  689. X    }
  690. X    if (pipepid == 0) {
  691. X    close(p[0]);
  692. X    if (p[1] != 1) {
  693. X        dup2(p[1], 1);
  694. X        close(p[1]);
  695. X    }
  696. X    (*func)(fil);
  697. X    fflush(stdout);
  698. X    fflush(stderr);
  699. X    _exit(0);
  700. X    }
  701. X    close(p[1]);
  702. X    fclose(fil);
  703. X    str = afetch(fdpid,p[0],TRUE);
  704. X    str->str_u.str_useful = pipepid;
  705. X    return fdopen(p[0], "r");
  706. X}
  707. X
  708. Xcryptswitch()
  709. X{
  710. X    int ch;
  711. X#ifdef STDSTDIO
  712. X    /* cheat on stdio if possible */
  713. X    if (rsfp->_cnt > 0 && (*rsfp->_ptr & 0xff) != CRYPT_MAGIC_1)
  714. X    return;
  715. X#endif
  716. X    ch = getc(rsfp);
  717. X    if (ch == CRYPT_MAGIC_1) {
  718. X    if (getc(rsfp) == CRYPT_MAGIC_2) {
  719. X        rsfp = mypfiopen( rsfp, cryptfilter );
  720. X        preprocess = 1;    /* force call to pclose when done */
  721. X    }
  722. X    else
  723. X        fatal( "bad encryption format" );
  724. X    }
  725. X    else
  726. X    ungetc(ch,rsfp);
  727. X}
  728. X
  729. XFILE *
  730. Xcryptopen(cmd)        /* open a (possibly encrypted) program for input */
  731. Xchar    *cmd;
  732. X{
  733. X    FILE    *fil = fopen( cmd, "r" );
  734. X
  735. X    lastpipefile = Nullfp;
  736. X    pipepid = 0;
  737. X
  738. X    if( fil ) {
  739. X    int    ch = getc( fil );
  740. X    int    lines = 0;
  741. X    int    chars = 0;
  742. X
  743. X    /* Search for the magic cookie that starts the encrypted script,
  744. X    ** while still allowing a few lines of unencrypted text to let
  745. X    ** '#!' and the nih hack both continue to work.  (These lines
  746. X    ** will end up being ignored.)
  747. X    */
  748. X    while( ch != CRYPT_MAGIC_1 && ch != EOF && lines < 5 && chars < 300 ) {
  749. X        if( ch == '\n' )
  750. X        ++lines;
  751. X        ch = getc( fil );
  752. X        ++chars;
  753. X    }
  754. X
  755. X    if( ch == CRYPT_MAGIC_1 ) {
  756. X        if( (ch = getc( fil ) ) == CRYPT_MAGIC_2 ) {
  757. X        if( perldb ) fatal("can't debug an encrypted script");
  758. X        /* we found it, decrypt the rest of the file */
  759. X        fil = mypfiopen( fil, cryptfilter );
  760. X        return( lastpipefile = fil );
  761. X        } else
  762. X        /* if its got MAGIC 1 without MAGIC 2, too bad */
  763. X        fatal( "bad encryption format" );
  764. X    }
  765. X
  766. X    /* this file is not encrypted - rewind and process it normally */
  767. X    rewind( fil );
  768. X    }
  769. X
  770. X    return( fil );
  771. X}
  772. X
  773. XVOID
  774. Xcryptclose(fil)
  775. XFILE    *fil;
  776. X{
  777. X    if( fil == Nullfp )
  778. X    return;
  779. X
  780. X    if( fil == lastpipefile )
  781. X    mypclose( fil );
  782. X    else
  783. X    fclose( fil );
  784. X}
  785. X#endif /* !MSDOS */
  786. X
  787. X#endif /* CRYPTSCRIPT */
  788. !STUFFY!FUNK!
  789. echo Extracting perly.fixer
  790. sed >perly.fixer <<'!STUFFY!FUNK!' -e 's/X//'
  791. X#!/bin/sh
  792. X
  793. X#  Hacks to make it work with Interactive's SysVr3 Version 2.2
  794. X#   doughera@lafvax.lafayette.edu (Andy Dougherty)   3/23/91
  795. X
  796. Xinput=$1
  797. Xoutput=$2
  798. Xtmp=/tmp/f$$
  799. X
  800. Xplan="unknown"
  801. X
  802. X#  Test for BSD 4.3 version.
  803. Xegrep 'YYSTYPE[     ]*yyv\[ *YYMAXDEPTH *\];
  804. Xshort[  ]*yys\[ *YYMAXDEPTH *\] *;
  805. Xyyps *= *&yys\[ *-1 *\];
  806. Xyypv *= *&yyv\[ *-1 *\];
  807. Xif *\( *\+\+yyps *> *&yys\[ *YYMAXDEPTH *\] *\)' $input >$tmp
  808. X
  809. Xset `wc -l $tmp`
  810. Xif test "$1" = "5"; then
  811. X      plan="bsd43"
  812. Xfi
  813. X
  814. Xif test "$plan" = "unknown"; then
  815. X    #   Test for ISC 2.2 version.
  816. Xegrep 'YYSTYPE[     ]*yyv\[ *YYMAXDEPTH *\];
  817. Xint[    ]*yys\[ *YYMAXDEPTH *\] *;
  818. Xyyps *= *&yys\[ *-1 *\];
  819. Xyypv *= *&yyv\[ *-1 *\];
  820. Xif *\( *\+\+yy_ps *>= *&yys\[ *YYMAXDEPTH *\] *\)' $input >$tmp
  821. X
  822. X    set `wc -l $tmp`
  823. X    if test "$1" = "5"; then
  824. X    plan="isc"
  825. X    fi
  826. Xfi
  827. X
  828. Xcase "$plan" in
  829. X    #######################################################
  830. X    "bsd43")
  831. X    echo "Patching perly.c to allow dynamic yacc stack allocation"
  832. X    echo "Assuming bsd4.3 yaccpar"
  833. X    cat >$tmp <<'END'
  834. X/YYSTYPE[     ]*yyv\[ *YYMAXDEPTH *\];/c\
  835. Xint yymaxdepth = YYMAXDEPTH;\
  836. XYYSTYPE *yyv; /* where the values are stored */\
  837. Xshort *yys;\
  838. Xshort *maxyyps;
  839. X
  840. X/short[     ]*yys\[ *YYMAXDEPTH *\] *;/d
  841. X
  842. X/yyps *= *&yys\[ *-1 *\];/d
  843. X
  844. X/yypv *= *&yyv\[ *-1 *\];/c\
  845. X\    if (!yyv) {\
  846. X\        yyv = (YYSTYPE*) malloc(yymaxdepth * sizeof(YYSTYPE));\
  847. X\        yys = (short*) malloc(yymaxdepth * sizeof(short));\
  848. X\        maxyyps = &yys[yymaxdepth];\
  849. X\    }\
  850. X\    yyps = &yys[-1];\
  851. X\    yypv = &yyv[-1];
  852. X
  853. X
  854. X/if *( *\+\+yyps *> *&yys\[ *YYMAXDEPTH *\] *)/c\
  855. X\        if( ++yyps >= maxyyps ) {\
  856. X\            int tv = yypv - yyv;\
  857. X\            int ts = yyps - yys;\
  858. X\
  859. X\            yymaxdepth *= 2;\
  860. X\            yyv = (YYSTYPE*)realloc((char*)yyv,\
  861. X\              yymaxdepth*sizeof(YYSTYPE));\
  862. X\            yys = (short*)realloc((char*)yys,\
  863. X\              yymaxdepth*sizeof(short));\
  864. X\            yyps = yys + ts;\
  865. X\            yypv = yyv + tv;\
  866. X\            maxyyps = &yys[yymaxdepth];\
  867. X\        }
  868. X
  869. X/yacc stack overflow.*}/d
  870. X/yacc stack overflow/,/}/d
  871. XEND
  872. X    sed -f $tmp <$input >$output ;;
  873. X
  874. X    #######################################################
  875. X    "isc") # Interactive Systems 2.2  version
  876. X    echo "Patching perly.c to allow dynamic yacc stack allocation"
  877. X    echo "Assuming Interactive SysVr3 2.2 yaccpar"
  878. X    # Easier to simply put whole script here than to modify the
  879. X    # bsd script with sed.
  880. X    # Main changes:  yaccpar sometimes uses yy_ps and yy_pv
  881. X    # which are local register variables.
  882. X    #  if(++yyps > YYMAXDEPTH) had opening brace on next line.
  883. X    # I've kept that brace in along with a call to yyerror if
  884. X    # realloc fails. (Actually, I just don't know how to do
  885. X    # multi-line matches in sed.)
  886. X    cat > $tmp << 'END'
  887. X/YYSTYPE[     ]*yyv\[ *YYMAXDEPTH *\];/c\
  888. Xint yymaxdepth = YYMAXDEPTH;\
  889. XYYSTYPE *yyv; /* where the values are stored */\
  890. Xint *yys;\
  891. Xint *maxyyps;
  892. X
  893. X/int[     ]*yys\[ *YYMAXDEPTH *\] *;/d
  894. X
  895. X/yyps *= *&yys\[ *-1 *\];/d
  896. X
  897. X/yypv *= *&yyv\[ *-1 *\];/c\
  898. X\    if (!yyv) {\
  899. X\        yyv = (YYSTYPE*) malloc(yymaxdepth * sizeof(YYSTYPE));\
  900. X\        yys = (int*) malloc(yymaxdepth * sizeof(int));\
  901. X\        maxyyps = &yys[yymaxdepth];\
  902. X\    }\
  903. X\    yyps = &yys[-1];\
  904. X\    yypv = &yyv[-1];
  905. X
  906. X/if *( *\+\+yy_ps *>= *&yys\[ *YYMAXDEPTH *\] *)/c\
  907. X\        if( ++yy_ps >= maxyyps ) {\
  908. X\            int tv = yy_pv - yyv;\
  909. X\            int ts = yy_ps - yys;\
  910. X\
  911. X\            yymaxdepth *= 2;\
  912. X\            yyv = (YYSTYPE*)realloc((char*)yyv,\
  913. X\              yymaxdepth*sizeof(YYSTYPE));\
  914. X\            yys = (int*)realloc((char*)yys,\
  915. X\              yymaxdepth*sizeof(int));\
  916. X\            yy_ps = yyps = yys + ts;\
  917. X\            yy_pv = yypv = yyv + tv;\
  918. X\            maxyyps = &yys[yymaxdepth];\
  919. X\        }\
  920. X\        if (yyv == NULL || yys == NULL)
  921. XEND
  922. X    sed -f $tmp < $input > $output ;;
  923. X
  924. X    ######################################################
  925. X    # Plan still unknown
  926. X    *) mv $input $output;
  927. Xesac
  928. X
  929. Xrm -rf $tmp $input
  930. !STUFFY!FUNK!
  931. echo Extracting msdos/popen.c
  932. sed >msdos/popen.c <<'!STUFFY!FUNK!' -e 's/X//'
  933. X/* $Header: popen.c,v 4.0 91/03/20 01:34:50 lwall Locked $
  934. X *
  935. X *    (C) Copyright 1988, 1990 Diomidis Spinellis.
  936. X *
  937. X *    You may distribute under the terms of the GNU General Public License
  938. X *    as specified in the README file that comes with the perl 3.0 kit.
  939. X *
  940. X * $Log:    popen.c,v $
  941. X * Revision 4.0  91/03/20  01:34:50  lwall
  942. X * 4.0 baseline.
  943. X * 
  944. X * Revision 3.0.1.2  90/08/09  04:04:42  lwall
  945. X * patch19: various MSDOS and OS/2 patches folded in
  946. X * 
  947. X * Revision 3.0.1.1  90/03/27  16:11:57  lwall
  948. X * patch16: MSDOS support
  949. X * 
  950. X * Revision 1.1  90/03/18  20:32:20  dds
  951. X * Initial revision
  952. X *
  953. X */
  954. X
  955. X/*
  956. X * Popen and pclose for MS-DOS
  957. X */
  958. X
  959. X#include <stdlib.h>
  960. X#include <stdio.h>
  961. X#include <process.h>
  962. X
  963. X/*
  964. X * Possible actions on an popened file
  965. X */
  966. Xenum action {
  967. X    delete,             /* Used for "r". Delete the tmp file */
  968. X    execute                /* Used for "w". Execute the command. */
  969. X};
  970. X
  971. X/*
  972. X * Linked list of things to do at the end of the program execution.
  973. X */
  974. Xstatic struct todo {
  975. X    FILE *f;            /* File we are working on (to fclose) */
  976. X    const char *name;        /* Name of the file (to unlink) */
  977. X    const char *command;        /* Command to execute */
  978. X    enum action what;        /* What to do (execute or delete) */
  979. X    struct todo *next;        /* Next structure */
  980. X} *todolist;
  981. X
  982. X
  983. X/* Clean up function */
  984. Xstatic int close_pipes(void);
  985. X
  986. X/*
  987. X * Add a file f running the command command on file name to the list
  988. X * of actions to be done at the end.  The action is specified in what.
  989. X * Return -1 on failure, 0 if ok.
  990. X */
  991. Xstatic int
  992. Xadd(FILE *f, const char *command, const char *name, enum action what)
  993. X{
  994. X    struct todo    *p;
  995. X
  996. X    if ((p = (struct todo *) malloc(sizeof(struct todo))) == NULL)
  997. X        return -1;
  998. X    p->f = f;
  999. X    p->command = command;
  1000. X    p->name = name;
  1001. X    p->what = what;
  1002. X    p->next = todolist;
  1003. X    todolist = p;
  1004. X    return 0;
  1005. X}
  1006. X
  1007. XFILE *
  1008. Xmypopen(const char *command, const char *t)
  1009. X{
  1010. X    char buff[256];
  1011. X    char *name;
  1012. X    FILE *f;
  1013. X    static init = 0;
  1014. X
  1015. X    if (!init)
  1016. X        if (onexit(close_pipes) == NULL)
  1017. X            return NULL;
  1018. X        else
  1019. X            init++;
  1020. X
  1021. X    if ((name = tempnam((char*)NULL, "pp")) == NULL)
  1022. X        return NULL;
  1023. X
  1024. X    switch (*t) {
  1025. X    case 'r':
  1026. X        sprintf(buff, "%s >%s", command, name);
  1027. X        if (system(buff) || (f = fopen(name, "r")) == NULL) {
  1028. X            free(name);
  1029. X            return NULL;
  1030. X        }
  1031. X        if (add(f, command, name, delete)) {
  1032. X            (void)fclose(f);
  1033. X            (void)unlink(name);
  1034. X            free(name);
  1035. X            return NULL;
  1036. X        }
  1037. X        return f;
  1038. X    case 'w':
  1039. X        if ((f = fopen(name, "w")) == NULL) {
  1040. X            free(name);
  1041. X            return NULL;
  1042. X        }
  1043. X        if (add(f, command, name, execute)) {
  1044. X            (void)fclose(f);
  1045. X            (void)unlink(name);
  1046. X            free(name);
  1047. X            return NULL;
  1048. X        }
  1049. X        return f;
  1050. X    default:
  1051. X        free(name);
  1052. X        return NULL;
  1053. X    }
  1054. X}
  1055. X
  1056. Xint
  1057. Xmypclose(FILE *f)
  1058. X{
  1059. X    struct todo *p, **prev;
  1060. X    char buff[256];
  1061. X    const char *name;
  1062. X    int status;
  1063. X
  1064. X    for (p = todolist, prev = &todolist; p; prev = &(p->next), p = p->next)
  1065. X        if (p->f == f) {
  1066. X            *prev = p->next;
  1067. X            name = p->name;
  1068. X            switch (p->what) {
  1069. X            case delete:
  1070. X                free(p);
  1071. X                if (fclose(f) == EOF) {
  1072. X                    (void)unlink(name);
  1073. X                    status = EOF;
  1074. X                } else if (unlink(name) < 0)
  1075. X                    status = EOF;
  1076. X                else
  1077. X                    status = 0;
  1078. X                free((void*)name);
  1079. X                return status;
  1080. X            case execute:
  1081. X                (void)sprintf(buff, "%s <%s", p->command, p->name);
  1082. X                free(p);
  1083. X                if (fclose(f) == EOF) {
  1084. X                    (void)unlink(name);
  1085. X                    status = EOF;
  1086. X                } else if (system(buff)) {
  1087. X                    (void)unlink(name);
  1088. X                    status = EOF;
  1089. X                } else if (unlink(name) < 0)
  1090. X                    status = EOF;
  1091. X                else
  1092. X                    status = 0;
  1093. X                free((void*)name);
  1094. X                return status;
  1095. X            default:
  1096. X                return EOF;
  1097. X            }
  1098. X        }
  1099. X    return EOF;
  1100. X}
  1101. X
  1102. X/*
  1103. X * Clean up at the end.  Called by the onexit handler.
  1104. X */
  1105. Xstatic int
  1106. Xclose_pipes(void)
  1107. X{
  1108. X    struct todo    *p;
  1109. X
  1110. X    for (p = todolist; p; p = p->next)
  1111. X        (void)mypclose(p->f);
  1112. X    return 0;
  1113. X}
  1114. !STUFFY!FUNK!
  1115. echo Extracting lib/termcap.pl
  1116. sed >lib/termcap.pl <<'!STUFFY!FUNK!' -e 's/X//'
  1117. X;# $Header: termcap.pl,v 4.0 91/03/20 01:26:33 lwall Locked $
  1118. X;#
  1119. X;# Usage:
  1120. X;#    require 'ioctl.pl';
  1121. X;#    ioctl(TTY,$TIOCGETP,$foo);
  1122. X;#    ($ispeed,$ospeed) = unpack('cc',$foo);
  1123. X;#    require 'termcap.pl';
  1124. X;#    &Tgetent('vt100');    # sets $TC{'cm'}, etc.
  1125. X;#    &Tputs(&Tgoto($TC{'cm'},$col,$row), 0, 'FILEHANDLE');
  1126. X;#    &Tputs($TC{'dl'},$affcnt,'FILEHANDLE');
  1127. X;#
  1128. Xsub Tgetent {
  1129. X    local($TERM) = @_;
  1130. X    local($TERMCAP,$_,$entry,$loop,$field);
  1131. X
  1132. X    warn "Tgetent: no ospeed set" unless $ospeed;
  1133. X    foreach $key (keys(TC)) {
  1134. X    delete $TC{$key};
  1135. X    }
  1136. X    $TERM = $ENV{'TERM'} unless $TERM;
  1137. X    $TERMCAP = $ENV{'TERMCAP'};
  1138. X    $TERMCAP = '/etc/termcap' unless $TERMCAP;
  1139. X    if ($TERMCAP !~ m:^/:) {
  1140. X    if (index($TERMCAP,"|$TERM|") < $[) {
  1141. X        $TERMCAP = '/etc/termcap';
  1142. X    }
  1143. X    }
  1144. X    if ($TERMCAP =~ m:^/:) {
  1145. X    $entry = '';
  1146. X    do {
  1147. X        $loop = "
  1148. X        open(TERMCAP,'<$TERMCAP') || die \"Can't open $TERMCAP\";
  1149. X        while (<TERMCAP>) {
  1150. X        next if /^#/;
  1151. X        next if /^\t/;
  1152. X        if (/\\|$TERM[:\\|]/) {
  1153. X            chop;
  1154. X            while (chop eq '\\\\') {
  1155. X            \$_ .= <TERMCAP>;
  1156. X            chop;
  1157. X            }
  1158. X            \$_ .= ':';
  1159. X            last;
  1160. X        }
  1161. X        }
  1162. X        close TERMCAP;
  1163. X        \$entry .= \$_;
  1164. X        ";
  1165. X        eval $loop;
  1166. X    } while s/:tc=([^:]+):/:/ && ($TERM = $1);
  1167. X    $TERMCAP = $entry;
  1168. X    }
  1169. X
  1170. X    foreach $field (split(/:[\s:\\]*/,$TERMCAP)) {
  1171. X    if ($field =~ /^\w\w$/) {
  1172. X        $TC{$field} = 1;
  1173. X    }
  1174. X    elsif ($field =~ /^(\w\w)#(.*)/) {
  1175. X        $TC{$1} = $2 if $TC{$1} eq '';
  1176. X    }
  1177. X    elsif ($field =~ /^(\w\w)=(.*)/) {
  1178. X        $entry = $1;
  1179. X        $_ = $2;
  1180. X        s/\\E/\033/g;
  1181. X        s/\\(\d\d\d)/pack('c',$1 & 0177)/eg;
  1182. X        s/\\n/\n/g;
  1183. X        s/\\r/\r/g;
  1184. X        s/\\t/\t/g;
  1185. X        s/\\b/\b/g;
  1186. X        s/\\f/\f/g;
  1187. X        s/\\\^/\377/g;
  1188. X        s/\^\?/\177/g;
  1189. X        s/\^(.)/pack('c',ord($1) & 31)/eg;
  1190. X        s/\\(.)/$1/g;
  1191. X        s/\377/^/g;
  1192. X        $TC{$entry} = $_ if $TC{$entry} eq '';
  1193. X    }
  1194. X    }
  1195. X    $TC{'pc'} = "\0" if $TC{'pc'} eq '';
  1196. X    $TC{'bc'} = "\b" if $TC{'bc'} eq '';
  1197. X}
  1198. X
  1199. X@Tputs = (0,200,133.3,90.9,74.3,66.7,50,33.3,16.7,8.3,5.5,4.1,2,1,.5,.2);
  1200. X
  1201. Xsub Tputs {
  1202. X    local($string,$affcnt,$FH) = @_;
  1203. X    local($ms);
  1204. X    if ($string =~ /(^[\d.]+)(\*?)(.*)$/) {
  1205. X    $ms = $1;
  1206. X    $ms *= $affcnt if $2;
  1207. X    $string = $3;
  1208. X    $decr = $Tputs[$ospeed];
  1209. X    if ($decr > .1) {
  1210. X        $ms += $decr / 2;
  1211. X        $string .= $TC{'pc'} x ($ms / $decr);
  1212. X    }
  1213. X    }
  1214. X    print $FH $string if $FH;
  1215. X    $string;
  1216. X}
  1217. X
  1218. Xsub Tgoto {
  1219. X    local($string) = shift(@_);
  1220. X    local($result) = '';
  1221. X    local($after) = '';
  1222. X    local($code,$tmp) = @_;
  1223. X    local(@tmp);
  1224. X    @tmp = ($tmp,$code);
  1225. X    local($online) = 0;
  1226. X    while ($string =~ /^([^%]*)%(.)(.*)/) {
  1227. X    $result .= $1;
  1228. X    $code = $2;
  1229. X    $string = $3;
  1230. X    if ($code eq 'd') {
  1231. X        $result .= sprintf("%d",shift(@tmp));
  1232. X    }
  1233. X    elsif ($code eq '.') {
  1234. X        $tmp = shift(@tmp);
  1235. X        if ($tmp == 0 || $tmp == 4 || $tmp == 10) {
  1236. X        if ($online) {
  1237. X            ++$tmp, $after .= $TC{'up'} if $TC{'up'};
  1238. X        }
  1239. X        else {
  1240. X            ++$tmp, $after .= $TC{'bc'};
  1241. X        }
  1242. X        }
  1243. X        $result .= sprintf("%c",$tmp);
  1244. X        $online = !$online;
  1245. X    }
  1246. X    elsif ($code eq '+') {
  1247. X        $result .= sprintf("%c",shift(@tmp)+ord($string));
  1248. X        $string = substr($string,1,99);
  1249. X        $online = !$online;
  1250. X    }
  1251. X    elsif ($code eq 'r') {
  1252. X        ($code,$tmp) = @tmp;
  1253. X        @tmp = ($tmp,$code);
  1254. X        $online = !$online;
  1255. X    }
  1256. X    elsif ($code eq '>') {
  1257. X        ($code,$tmp,$string) = unpack("CCa99",$string);
  1258. X        if ($tmp[$[] > $code) {
  1259. X        $tmp[$[] += $tmp;
  1260. X        }
  1261. X    }
  1262. X    elsif ($code eq '2') {
  1263. X        $result .= sprintf("%02d",shift(@tmp));
  1264. X        $online = !$online;
  1265. X    }
  1266. X    elsif ($code eq '3') {
  1267. X        $result .= sprintf("%03d",shift(@tmp));
  1268. X        $online = !$online;
  1269. X    }
  1270. X    elsif ($code eq 'i') {
  1271. X        ($code,$tmp) = @tmp;
  1272. X        @tmp = ($code+1,$tmp+1);
  1273. X    }
  1274. X    else {
  1275. X        return "OOPS";
  1276. X    }
  1277. X    }
  1278. X    $result . $string . $after;
  1279. X}
  1280. X
  1281. X1;
  1282. !STUFFY!FUNK!
  1283. echo Extracting t/cmd/subval.t
  1284. sed >t/cmd/subval.t <<'!STUFFY!FUNK!' -e 's/X//'
  1285. X#!./perl
  1286. X
  1287. X# $Header: subval.t,v 4.0 91/03/20 01:49:40 lwall Locked $
  1288. X
  1289. Xsub foo1 {
  1290. X    'true1';
  1291. X    if ($_[0]) { 'true2'; }
  1292. X}
  1293. X
  1294. Xsub foo2 {
  1295. X    'true1';
  1296. X    if ($_[0]) { return 'true2'; } else { return 'true3'; }
  1297. X    'true0';
  1298. X}
  1299. X
  1300. Xsub foo3 {
  1301. X    'true1';
  1302. X    unless ($_[0]) { 'true2'; }
  1303. X}
  1304. X
  1305. Xsub foo4 {
  1306. X    'true1';
  1307. X    unless ($_[0]) { 'true2'; } else { 'true3'; }
  1308. X}
  1309. X
  1310. Xsub foo5 {
  1311. X    'true1';
  1312. X    'true2' if $_[0];
  1313. X}
  1314. X
  1315. Xsub foo6 {
  1316. X    'true1';
  1317. X    'true2' unless $_[0];
  1318. X}
  1319. X
  1320. Xprint "1..34\n";
  1321. X
  1322. Xif (do foo1(0) eq '0') {print "ok 1\n";} else {print "not ok 1 $foo\n";}
  1323. Xif (do foo1(1) eq 'true2') {print "ok 2\n";} else {print "not ok 2\n";}
  1324. Xif (do foo2(0) eq 'true3') {print "ok 3\n";} else {print "not ok 3\n";}
  1325. Xif (do foo2(1) eq 'true2') {print "ok 4\n";} else {print "not ok 4\n";}
  1326. X
  1327. Xif (do foo3(0) eq 'true2') {print "ok 5\n";} else {print "not ok 5\n";}
  1328. Xif (do foo3(1) eq '1') {print "ok 6\n";} else {print "not ok 6\n";}
  1329. Xif (do foo4(0) eq 'true2') {print "ok 7\n";} else {print "not ok 7\n";}
  1330. Xif (do foo4(1) eq 'true3') {print "ok 8\n";} else {print "not ok 8\n";}
  1331. X
  1332. Xif (do foo5(0) eq '0') {print "ok 9\n";} else {print "not ok 9\n";}
  1333. Xif (do foo5(1) eq 'true2') {print "ok 10\n";} else {print "not ok 10\n";}
  1334. Xif (do foo6(0) eq 'true2') {print "ok 11\n";} else {print "not ok 11\n";}
  1335. Xif (do foo6(1) eq '1') {print "ok 12\n";} else {print "not ok 12 $x\n";}
  1336. X
  1337. X# Now test to see that recursion works using a Fibonacci number generator
  1338. X
  1339. Xsub fib {
  1340. X    local($arg) = @_;
  1341. X    local($foo);
  1342. X    $level++;
  1343. X    if ($arg <= 2) {
  1344. X    $foo = 1;
  1345. X    }
  1346. X    else {
  1347. X    $foo = do fib($arg-1) + do fib($arg-2);
  1348. X    }
  1349. X    $level--;
  1350. X    $foo;
  1351. X}
  1352. X
  1353. X@good = (0,1,1,2,3,5,8,13,21,34,55,89);
  1354. X
  1355. Xfor ($i = 1; $i <= 10; $i++) {
  1356. X    $foo = $i + 12;
  1357. X    if (do fib($i) == $good[$i]) {
  1358. X    print "ok $foo\n";
  1359. X    }
  1360. X    else {
  1361. X    print "not ok $foo\n";
  1362. X    }
  1363. X}
  1364. X
  1365. Xsub ary1 {
  1366. X    (1,2,3);
  1367. X}
  1368. X
  1369. Xprint &ary1 eq 3 ? "ok 23\n" : "not ok 23\n";
  1370. X
  1371. Xprint join(':',&ary1) eq '1:2:3' ? "ok 24\n" : "not ok 24\n";
  1372. X
  1373. Xsub ary2 {
  1374. X    do {
  1375. X    return (1,2,3);
  1376. X    (3,2,1);
  1377. X    };
  1378. X    0;
  1379. X}
  1380. X
  1381. Xprint &ary2 eq 3 ? "ok 25\n" : "not ok 25\n";
  1382. X
  1383. X$x = join(':',&ary2);
  1384. Xprint $x eq '1:2:3' ? "ok 26\n" : "not ok 26 $x\n";
  1385. X
  1386. Xsub somesub {
  1387. X    local($num,$P,$F,$L) = @_;
  1388. X    ($p,$f,$l) = caller;
  1389. X    print "$p:$f:$l" eq "$P:$F:$L" ? "ok $num\n" : "not ok $num\n";
  1390. X}
  1391. X
  1392. X&somesub(27, 'main', __FILE__, __LINE__);
  1393. X
  1394. Xpackage foo;
  1395. X&main'somesub(28, 'foo', __FILE__, __LINE__);
  1396. X
  1397. Xpackage main;
  1398. X$i = 28;
  1399. Xopen(FOO,">Cmd_subval.tmp");
  1400. Xprint FOO "blah blah\n";
  1401. Xclose FOO;
  1402. X
  1403. X&file_main(*F);
  1404. Xclose F;
  1405. X&info_main;
  1406. X
  1407. X&file_package(*F);
  1408. Xclose F;
  1409. X&info_package;
  1410. X
  1411. Xunlink 'Cmd_subval.tmp';
  1412. X
  1413. Xsub file_main {
  1414. X        local(*F) = @_;
  1415. X
  1416. X        open(F, 'Cmd_subval.tmp') || die "can't open\n";
  1417. X    $i++;
  1418. X        eof F ? print "not ok $i\n" : print "ok $i\n";
  1419. X}
  1420. X
  1421. Xsub info_main {
  1422. X        local(*F);
  1423. X
  1424. X        open(F, 'Cmd_subval.tmp') || die "test: can't open\n";
  1425. X    $i++;
  1426. X        eof F ? print "not ok $i\n" : print "ok $i\n";
  1427. X        &iseof(*F);
  1428. X    close F;
  1429. X}
  1430. X
  1431. Xsub iseof {
  1432. X        local(*UNIQ) = @_;
  1433. X
  1434. X    $i++;
  1435. X        eof UNIQ ? print "(not ok $i)\n" : print "ok $i\n";
  1436. X}
  1437. X
  1438. X{package foo;
  1439. X
  1440. X sub main'file_package {
  1441. X        local(*F) = @_;
  1442. X
  1443. X        open(F, 'Cmd_subval.tmp') || die "can't open\n";
  1444. X    $main'i++;
  1445. X        eof F ? print "not ok $main'i\n" : print "ok $main'i\n";
  1446. X }
  1447. X
  1448. X sub main'info_package {
  1449. X        local(*F);
  1450. X
  1451. X        open(F, 'Cmd_subval.tmp') || die "can't open\n";
  1452. X    $main'i++;
  1453. X        eof F ? print "not ok $main'i\n" : print "ok $main'i\n";
  1454. X        &iseof(*F);
  1455. X }
  1456. X
  1457. X sub iseof {
  1458. X        local(*UNIQ) = @_;
  1459. X
  1460. X    $main'i++;
  1461. X        eof UNIQ ? print "not ok $main'i\n" : print "ok $main'i\n";
  1462. X }
  1463. X}
  1464. !STUFFY!FUNK!
  1465. echo Extracting t/op/pat.t
  1466. sed >t/op/pat.t <<'!STUFFY!FUNK!' -e 's/X//'
  1467. X#!./perl
  1468. X
  1469. X# $Header: pat.t,v 4.0 91/03/20 01:54:01 lwall Locked $
  1470. X
  1471. Xprint "1..43\n";
  1472. X
  1473. X$x = "abc\ndef\n";
  1474. X
  1475. Xif ($x =~ /^abc/) {print "ok 1\n";} else {print "not ok 1\n";}
  1476. Xif ($x !~ /^def/) {print "ok 2\n";} else {print "not ok 2\n";}
  1477. X
  1478. X$* = 1;
  1479. Xif ($x =~ /^def/) {print "ok 3\n";} else {print "not ok 3\n";}
  1480. X$* = 0;
  1481. X
  1482. X$_ = '123';
  1483. Xif (/^([0-9][0-9]*)/) {print "ok 4\n";} else {print "not ok 4\n";}
  1484. X
  1485. Xif ($x =~ /^xxx/) {print "not ok 5\n";} else {print "ok 5\n";}
  1486. Xif ($x !~ /^abc/) {print "not ok 6\n";} else {print "ok 6\n";}
  1487. X
  1488. Xif ($x =~ /def/) {print "ok 7\n";} else {print "not ok 7\n";}
  1489. Xif ($x !~ /def/) {print "not ok 8\n";} else {print "ok 8\n";}
  1490. X
  1491. Xif ($x !~ /.def/) {print "ok 9\n";} else {print "not ok 9\n";}
  1492. Xif ($x =~ /.def/) {print "not ok 10\n";} else {print "ok 10\n";}
  1493. X
  1494. Xif ($x =~ /\ndef/) {print "ok 11\n";} else {print "not ok 11\n";}
  1495. Xif ($x !~ /\ndef/) {print "not ok 12\n";} else {print "ok 12\n";}
  1496. X
  1497. X$_ = 'aaabbbccc';
  1498. Xif (/(a*b*)(c*)/ && $1 eq 'aaabbb' && $2 eq 'ccc') {
  1499. X    print "ok 13\n";
  1500. X} else {
  1501. X    print "not ok 13\n";
  1502. X}
  1503. Xif (/(a+b+c+)/ && $1 eq 'aaabbbccc') {
  1504. X    print "ok 14\n";
  1505. X} else {
  1506. X    print "not ok 14\n";
  1507. X}
  1508. X
  1509. Xif (/a+b?c+/) {print "not ok 15\n";} else {print "ok 15\n";}
  1510. X
  1511. X$_ = 'aaabccc';
  1512. Xif (/a+b?c+/) {print "ok 16\n";} else {print "not ok 16\n";}
  1513. Xif (/a*b+c*/) {print "ok 17\n";} else {print "not ok 17\n";}
  1514. X
  1515. X$_ = 'aaaccc';
  1516. Xif (/a*b?c*/) {print "ok 18\n";} else {print "not ok 18\n";}
  1517. Xif (/a*b+c*/) {print "not ok 19\n";} else {print "ok 19\n";}
  1518. X
  1519. X$_ = 'abcdef';
  1520. Xif (/bcd|xyz/) {print "ok 20\n";} else {print "not ok 20\n";}
  1521. Xif (/xyz|bcd/) {print "ok 21\n";} else {print "not ok 21\n";}
  1522. X
  1523. Xif (m|bc/*d|) {print "ok 22\n";} else {print "not ok 22\n";}
  1524. X
  1525. Xif (/^$_$/) {print "ok 23\n";} else {print "not ok 23\n";}
  1526. X
  1527. X$* = 1;        # test 3 only tested the optimized version--this one is for real
  1528. Xif ("ab\ncd\n" =~ /^cd/) {print "ok 24\n";} else {print "not ok 24\n";}
  1529. X$* = 0;
  1530. X
  1531. X$XXX{123} = 123;
  1532. X$XXX{234} = 234;
  1533. X$XXX{345} = 345;
  1534. X
  1535. X@XXX = ('ok 25','not ok 25', 'ok 26','not ok 26','not ok 27');
  1536. Xwhile ($_ = shift(XXX)) {
  1537. X    ?(.*)? && (print $1,"\n");
  1538. X    /not/ && reset;
  1539. X    /not ok 26/ && reset 'X';
  1540. X}
  1541. X
  1542. Xwhile (($key,$val) = each(XXX)) {
  1543. X    print "not ok 27\n";
  1544. X    exit;
  1545. X}
  1546. X
  1547. Xprint "ok 27\n";
  1548. X
  1549. X'cde' =~ /[^ab]*/;
  1550. X'xyz' =~ //;
  1551. Xif ($& eq 'xyz') {print "ok 28\n";} else {print "not ok 28\n";}
  1552. X
  1553. X$foo = '[^ab]*';
  1554. X'cde' =~ /$foo/;
  1555. X'xyz' =~ //;
  1556. Xif ($& eq 'xyz') {print "ok 29\n";} else {print "not ok 29\n";}
  1557. X
  1558. X$foo = '[^ab]*';
  1559. X'cde' =~ /$foo/;
  1560. X'xyz' =~ /$null/;
  1561. Xif ($& eq 'xyz') {print "ok 30\n";} else {print "not ok 30\n";}
  1562. X
  1563. X$_ = 'abcdefghi';
  1564. X/def/;        # optimized up to cmd
  1565. Xif ("$`:$&:$'" eq 'abc:def:ghi') {print "ok 31\n";} else {print "not ok 31\n";}
  1566. X
  1567. X/cde/ + 0;    # optimized only to spat
  1568. Xif ("$`:$&:$'" eq 'ab:cde:fghi') {print "ok 32\n";} else {print "not ok 32\n";}
  1569. X
  1570. X/[d][e][f]/;    # not optimized
  1571. Xif ("$`:$&:$'" eq 'abc:def:ghi') {print "ok 33\n";} else {print "not ok 33\n";}
  1572. X
  1573. X$_ = 'now is the {time for all} good men to come to.';
  1574. X/ {([^}]*)}/;
  1575. Xif ($1 eq 'time for all') {print "ok 34\n";} else {print "not ok 34 $1\n";}
  1576. X
  1577. X$_ = 'xxx {3,4}  yyy   zzz';
  1578. Xprint /( {3,4})/ ? "ok 35\n" : "not ok 35\n";
  1579. Xprint $1 eq '   ' ? "ok 36\n" : "not ok 36\n";
  1580. Xprint /( {4,})/ ? "not ok 37\n" : "ok 37\n";
  1581. Xprint /( {2,3}.)/ ? "ok 38\n" : "not ok 38\n";
  1582. Xprint $1 eq '  y' ? "ok 39\n" : "not ok 39\n";
  1583. Xprint /(y{2,3}.)/ ? "ok 40\n" : "not ok 40\n";
  1584. Xprint $1 eq 'yyy ' ? "ok 41\n" : "not ok 41\n";
  1585. Xprint /x {3,4}/ ? "not ok 42\n" : "ok 42\n";
  1586. Xprint /^xxx {3,4}/ ? "not ok 43\n" : "ok 43\n";
  1587. !STUFFY!FUNK!
  1588. echo Extracting handy.h
  1589. sed >handy.h <<'!STUFFY!FUNK!' -e 's/X//'
  1590. X/* $Header: handy.h,v 4.0 91/03/20 01:22:15 lwall Locked $
  1591. X *
  1592. X *    Copyright (c) 1989, Larry Wall
  1593. X *
  1594. X *    You may distribute under the terms of the GNU General Public License
  1595. X *    as specified in the README file that comes with the perl 3.0 kit.
  1596. X *
  1597. X * $Log:    handy.h,v $
  1598. X * Revision 4.0  91/03/20  01:22:15  lwall
  1599. X * 4.0 baseline.
  1600. X * 
  1601. X */
  1602. X
  1603. X#ifdef NULL
  1604. X#undef NULL
  1605. X#endif
  1606. X#ifndef I286
  1607. X#  define NULL 0
  1608. X#else
  1609. X#  define NULL 0L
  1610. X#endif
  1611. X#define Null(type) ((type)NULL)
  1612. X#define Nullch Null(char*)
  1613. X#define Nullfp Null(FILE*)
  1614. X
  1615. X#ifdef UTS
  1616. X#define bool int
  1617. X#else
  1618. X#define bool char
  1619. X#endif
  1620. X
  1621. X#ifdef TRUE
  1622. X#undef TRUE
  1623. X#endif
  1624. X#ifdef FALSE
  1625. X#undef FALSE
  1626. X#endif
  1627. X#define TRUE (1)
  1628. X#define FALSE (0)
  1629. X
  1630. X#define Ctl(ch) (ch & 037)
  1631. X
  1632. X#define strNE(s1,s2) (strcmp(s1,s2))
  1633. X#define strEQ(s1,s2) (!strcmp(s1,s2))
  1634. X#define strLT(s1,s2) (strcmp(s1,s2) < 0)
  1635. X#define strLE(s1,s2) (strcmp(s1,s2) <= 0)
  1636. X#define strGT(s1,s2) (strcmp(s1,s2) > 0)
  1637. X#define strGE(s1,s2) (strcmp(s1,s2) >= 0)
  1638. X#define strnNE(s1,s2,l) (strncmp(s1,s2,l))
  1639. X#define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
  1640. X
  1641. X#define MEM_SIZE unsigned int
  1642. X
  1643. X/* Line numbers are unsigned, 16 bits. */
  1644. Xtypedef unsigned short line_t;
  1645. X#ifdef lint
  1646. X#define NOLINE ((line_t)0)
  1647. X#else
  1648. X#define NOLINE ((line_t) 65535)
  1649. X#endif
  1650. X
  1651. X#ifndef lint
  1652. X#ifndef LEAKTEST
  1653. Xchar *safemalloc();
  1654. Xchar *saferealloc();
  1655. Xvoid safefree();
  1656. X#ifndef MSDOS
  1657. X#define New(x,v,n,t)  (v = (t*)safemalloc((MEM_SIZE)((n) * sizeof(t))))
  1658. X#define Newc(x,v,n,t,c)  (v = (c*)safemalloc((MEM_SIZE)((n) * sizeof(t))))
  1659. X#define Newz(x,v,n,t) (v = (t*)safemalloc((MEM_SIZE)((n) * sizeof(t)))), \
  1660. X    bzero((char*)(v), (n) * sizeof(t))
  1661. X#define Renew(v,n,t) (v = (t*)saferealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t))))
  1662. X#define Renewc(v,n,t,c) (v = (c*)saferealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t))))
  1663. X#else
  1664. X#define New(x,v,n,t)  (v = (t*)safemalloc(((unsigned long)(n) * sizeof(t))))
  1665. X#define Newc(x,v,n,t,c)  (v = (c*)safemalloc(((unsigned long)(n) * sizeof(t))))
  1666. X#define Newz(x,v,n,t) (v = (t*)safemalloc(((unsigned long)(n) * sizeof(t)))), \
  1667. X    bzero((char*)(v), (n) * sizeof(t))
  1668. X#define Renew(v,n,t) (v = (t*)saferealloc((char*)(v),((unsigned long)(n)*sizeof(t))))
  1669. X#define Renewc(v,n,t,c) (v = (c*)saferealloc((char*)(v),((unsigned long)(n)*sizeof(t))))
  1670. X#endif /* MSDOS */
  1671. X#define Safefree(d) safefree((char*)d)
  1672. X#define Str_new(x,len) str_new(len)
  1673. X#else /* LEAKTEST */
  1674. Xchar *safexmalloc();
  1675. Xchar *safexrealloc();
  1676. Xvoid safexfree();
  1677. X#define New(x,v,n,t)  (v = (t*)safexmalloc(x,(MEM_SIZE)((n) * sizeof(t))))
  1678. X#define Newc(x,v,n,t,c)  (v = (c*)safexmalloc(x,(MEM_SIZE)((n) * sizeof(t))))
  1679. X#define Newz(x,v,n,t) (v = (t*)safexmalloc(x,(MEM_SIZE)((n) * sizeof(t)))), \
  1680. X    bzero((char*)(v), (n) * sizeof(t))
  1681. X#define Renew(v,n,t) (v = (t*)safexrealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t))))
  1682. X#define Renewc(v,n,t,c) (v = (c*)safexrealloc((char*)(v),(MEM_SIZE)((n)*sizeof(t))))
  1683. X#define Safefree(d) safexfree((char*)d)
  1684. X#define Str_new(x,len) str_new(x,len)
  1685. X#define MAXXCOUNT 1200
  1686. Xlong xcount[MAXXCOUNT];
  1687. Xlong lastxcount[MAXXCOUNT];
  1688. X#endif /* LEAKTEST */
  1689. X#define Copy(s,d,n,t) (void)bcopy((char*)(s),(char*)(d), (n) * sizeof(t))
  1690. X#define Zero(d,n,t) (void)bzero((char*)(d), (n) * sizeof(t))
  1691. X#else /* lint */
  1692. X#define New(x,v,n,s) (v = Null(s *))
  1693. X#define Newc(x,v,n,s,c) (v = Null(s *))
  1694. X#define Newz(x,v,n,s) (v = Null(s *))
  1695. X#define Renew(v,n,s) (v = Null(s *))
  1696. X#define Copy(s,d,n,t)
  1697. X#define Zero(d,n,t)
  1698. X#define Safefree(d) d = d
  1699. X#endif /* lint */
  1700. !STUFFY!FUNK!
  1701. echo Extracting usub/pager
  1702. sed >usub/pager <<'!STUFFY!FUNK!' -e 's/X//'
  1703. X#!./curseperl
  1704. X
  1705. Xeval <<'EndOfMain';   $evaloffset = __LINE__;
  1706. X
  1707. X    $SIG{'INT'} = 'endit';
  1708. X    $| = 1;        # command buffering on stdout
  1709. X    &initterm;
  1710. X    &inithelp;
  1711. X    &slurpfile && &pagearray;
  1712. X
  1713. XEndOfMain
  1714. X
  1715. X&endit;
  1716. X
  1717. X################################################################################
  1718. X
  1719. Xsub initterm {
  1720. X
  1721. X    &initscr; &cbreak; &noecho; &scrollok($stdscr, 1);
  1722. X    &defbell unless defined &bell;
  1723. X
  1724. X    $lines = $LINES; $lines1 = $lines - 1; $lines2 = $lines - 2;
  1725. X    $cols = $COLS;   $cols1  = $cols  - 1; $cols2  = $cols  - 2;;
  1726. X
  1727. X    $dl = &getcap('dl');
  1728. X    $al = &getcap('al');
  1729. X    $ho = &getcap('ho');
  1730. X    $ce = &getcap('ce');
  1731. X}
  1732. X
  1733. Xsub slurpfile {
  1734. X    while (<>) {
  1735. X    s/^(\t+)/'        ' x length($1)/e;
  1736. X    &expand($_) if /\t/;
  1737. X    if (length($_) < $cols) {
  1738. X        push(@lines, $_);
  1739. X    }
  1740. X    else {
  1741. X        while ($_ && $_ ne "\n") {
  1742. X        push(@lines, substr($_,0,$cols));
  1743. X        substr($_,0,$cols) = '';
  1744. X        }
  1745. X    }
  1746. X    }
  1747. X    1;
  1748. X}
  1749. X
  1750. Xsub drawscreen {
  1751. X    &move(0,0);
  1752. X    for ($line .. $line + $lines2) {
  1753. X    &addstr($lines[$_]);
  1754. X    }
  1755. X    &clrtobot;
  1756. X    &percent;
  1757. X    &refresh;
  1758. X}
  1759. X
  1760. Xsub expand {
  1761. X    while (($off = index($_[0],"\t")) >= 0) {
  1762. X    substr($_[0], $off, 1) = ' ' x (8 - $off % 8);
  1763. X    }
  1764. X}
  1765. X
  1766. Xsub pagearray {
  1767. X    $line = 0;
  1768. X
  1769. X    $| = 1;
  1770. X
  1771. X    for (&drawscreen;;&drawscreen) {
  1772. X
  1773. X    $ch = &getch;
  1774. X    $ch = 'j' if $ch eq "\n";
  1775. X
  1776. X    if ($ch eq ' ') {
  1777. X        last if $percent >= 100;
  1778. X        &move(0,0);
  1779. X        $line += $lines1;
  1780. X    }
  1781. X    elsif ($ch eq 'b') {
  1782. X        $line -= $lines1;
  1783. X        &move(0,0);
  1784. X        $line = 0 if $line < 0;
  1785. X    }
  1786. X    elsif ($ch eq 'j') {
  1787. X        next if $percent >= 100;
  1788. X        $line += 1;
  1789. X        if ($dl && $ho) {
  1790. X        print $ho, $dl;
  1791. X        &mvcur(0,0,$lines2,0);
  1792. X        print $ce,$lines[$line+$lines2],$ce;
  1793. X        &wmove($curscr,0,0);
  1794. X        &wdeleteln($curscr);
  1795. X        &wmove($curscr,$lines2,0);
  1796. X        &waddstr($curscr,$lines[$line+$lines2]);
  1797. X        }
  1798. X        &wmove($stdscr,0,0);
  1799. X        &wdeleteln($stdscr);
  1800. X        &wmove($stdscr,$lines2,0);
  1801. X        &waddstr($stdscr,$lines[$line+$lines2]);
  1802. X        &percent;
  1803. X        &refresh;
  1804. X        redo;
  1805. X    }
  1806. X    elsif ($ch eq 'k') {
  1807. X        next if $line <= 0;
  1808. X        $line -= 1;
  1809. X        if ($al && $ho && $ce) {
  1810. X        print $ho, $al, $ce, $lines[$line];
  1811. X        &wmove($curscr,0,0);
  1812. X        &winsertln($curscr);
  1813. X        &waddstr($curscr,$lines[$line]);
  1814. X        }
  1815. X        &wmove($stdscr,0,0);
  1816. X        &winsertln($stdscr);
  1817. X        &waddstr($stdscr,$lines[$line]);
  1818. X        &percent;
  1819. X        &refresh;
  1820. X        redo;
  1821. X    }
  1822. X    elsif ($ch eq "\f") {
  1823. X        &clear;
  1824. X    }
  1825. X    elsif ($ch eq 'q') {
  1826. X        last;
  1827. X    }
  1828. X    elsif ($ch eq 'h') {
  1829. X        &clear;
  1830. X        &help;
  1831. X        &clear;
  1832. X    }
  1833. X    else {
  1834. X        &bell;
  1835. X    }
  1836. X    }
  1837. X}
  1838. X
  1839. Xsub defbell {
  1840. X    eval q#
  1841. X    sub bell {
  1842. X        print "\007";
  1843. X    }
  1844. X    #;
  1845. X}
  1846. X
  1847. Xsub help {
  1848. X    local(*lines) = *helplines;
  1849. X    local($line);
  1850. X    &pagearray;
  1851. X}
  1852. X
  1853. Xsub inithelp {
  1854. X    @helplines = split(/\n/,<<'EOT');
  1855. X
  1856. X  h              Display this help.
  1857. X  q              Exit.
  1858. X
  1859. X  SPACE          Forward  screen.
  1860. X  b              Backward screen.
  1861. X  j, CR          Forward  1 line.
  1862. X  k              Backward 1 line.
  1863. X  FF             Repaint screen.
  1864. XEOT
  1865. X    for (@helplines) {
  1866. X    s/$/\n/;
  1867. X    }
  1868. X}
  1869. X
  1870. Xsub percent {
  1871. X    &standout;
  1872. X      $percent = int(($line + $lines1) * 100 / @lines);
  1873. X      &move($lines1,0);
  1874. X      &addstr("($percent%)");
  1875. X    &standend;
  1876. X    &clrtoeol;
  1877. X}
  1878. X
  1879. Xsub endit {
  1880. X    &move($lines1,0);
  1881. X    &clrtoeol;
  1882. X    &refresh;
  1883. X    &endwin;
  1884. X
  1885. X    if ($@) {
  1886. X    print "";                # force flush of stdout
  1887. X    $@ =~ s/\(eval\)/$0/ && $@ =~ s/line (\d+)/'line ' . ($1 + $evaloffset)/e;
  1888. X    die $@;
  1889. X    }
  1890. X
  1891. X    exit;
  1892. X}
  1893. !STUFFY!FUNK!
  1894. echo Extracting msdos/chdir.c
  1895. sed >msdos/chdir.c <<'!STUFFY!FUNK!' -e 's/X//'
  1896. X/*
  1897. X *    (C) Copyright 1990, 1991 Tom Dinger
  1898. X *
  1899. X *    You may distribute under the terms of the GNU General Public License
  1900. X *    as specified in the README file that comes with the perl 4.0 kit.
  1901. X *
  1902. X */
  1903. X
  1904. X/*
  1905. X * A "DOS-aware" chdir() function, that will change current drive as well.
  1906. X *
  1907. X *    chdir( "B:" )    -- changes to the default directory, on drive B:
  1908. X *    chdir( "C:\FOO" )  changes to the specified directory, on drive C:
  1909. X *    chdir( "\BAR" )    changes to the specified directory on the current
  1910. X *               drive.
  1911. X */
  1912. X
  1913. X#include <stdlib.h>
  1914. X#include <ctype.h>
  1915. X#include <direct.h>
  1916. X#include <dos.h>
  1917. X#include <errno.h>
  1918. X
  1919. X#include "config.h"
  1920. X#ifdef chdir
  1921. X#undef chdir
  1922. X#endif
  1923. X
  1924. X/* We should have the line:
  1925. X *
  1926. X * #define chdir perl_chdir
  1927. X *
  1928. X * in some header for perl (I put it in config.h) so that all
  1929. X * references to chdir() become references to this function.
  1930. X */
  1931. X
  1932. X/*------------------------------------------------------------------*/
  1933. X
  1934. X#if defined(BUGGY_MSC5)    /* only needed for MSC 5.1 */
  1935. X
  1936. Xint _chdrive( int drivenum )
  1937. X{
  1938. Xunsigned int    ndrives;
  1939. Xunsigned int    tmpdrive;
  1940. X
  1941. X
  1942. X_dos_setdrive( drivenum, &ndrives );
  1943. X
  1944. X/* check for illegal drive letter */
  1945. X_dos_getdrive( &tmpdrive );
  1946. X
  1947. Xreturn (tmpdrive != drivenum) ? -1 : 0 ;
  1948. X}
  1949. X
  1950. X#endif
  1951. X
  1952. X/*-----------------------------------------------------------------*/
  1953. X
  1954. Xint perl_chdir( char * path )
  1955. X{
  1956. Xint        drive_letter;
  1957. Xunsigned int    drivenum;
  1958. X
  1959. X
  1960. Xif ( path && *path && (path[1] == ':') )
  1961. X    {
  1962. X    /* The path starts with a drive letter */
  1963. X    /* Change current drive */
  1964. X    drive_letter = *path;
  1965. X    if ( isalpha(drive_letter) )
  1966. X    {
  1967. X    /* Drive letter legal */
  1968. X    if ( islower(drive_letter) )
  1969. X        drive_letter = toupper(drive_letter);
  1970. X    drivenum = drive_letter - 'A' + 1;
  1971. X
  1972. X    /* Change drive */
  1973. X    if ( _chdrive( drivenum ) == -1 )
  1974. X        {
  1975. X        /* Drive change failed -- must be illegal drive letter */
  1976. X        errno = ENODEV;
  1977. X        return -1;
  1978. X        }
  1979. X
  1980. X    /* Now see if that's all we do */
  1981. X    if ( ! path[2] )
  1982. X        return 0;        /* no path after drive -- all done */
  1983. X    }
  1984. X    /* else drive letter illegal -- fall into "normal" chdir */
  1985. X    }
  1986. X
  1987. X/* Here with some path as well */
  1988. Xreturn chdir( path );
  1989. X
  1990. X/* end perl_chdir() */
  1991. X}
  1992. !STUFFY!FUNK!
  1993. echo " "
  1994. echo "End of kit 32 (of 36)"
  1995. cat /dev/null >kit32isdone
  1996. run=''
  1997. config=''
  1998. 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 25 26 27 28 29 30 31 32 33 34 35 36; do
  1999.     if test -f kit${iskit}isdone; then
  2000.     run="$run $iskit"
  2001.     else
  2002.     todo="$todo $iskit"
  2003.     fi
  2004. done
  2005. case $todo in
  2006.     '')
  2007.     echo "You have run all your kits.  Please read README and then type Configure."
  2008.     for combo in *:AA; do
  2009.         if test -f "$combo"; then
  2010.         realfile=`basename $combo :AA`
  2011.         cat $realfile:[A-Z][A-Z] >$realfile
  2012.         rm -rf $realfile:[A-Z][A-Z]
  2013.         fi
  2014.     done
  2015.     rm -rf kit*isdone
  2016.     chmod 755 Configure
  2017.     ;;
  2018.     *)  echo "You have run$run."
  2019.     echo "You still need to run$todo."
  2020.     ;;
  2021. esac
  2022. : Someone might mail this, so...
  2023. exit
  2024.  
  2025. exit 0 # Just in case...
  2026. -- 
  2027. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2028. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2029. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2030. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2031.