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

  1. From: lwall@netlabs.com (Larry Wall)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i048:  perl - The perl programming language, Part30/36
  4. Message-ID: <1991Apr17.185832.2834@sparky.IMD.Sterling.COM>
  5. Date: 17 Apr 91 18:58:32 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: dbb0bc80 0eaf4762 315e6020 2cf4e6d7
  8.  
  9. Submitted-by: Larry Wall <lwall@netlabs.com>
  10. Posting-number: Volume 18, Issue 48
  11. Archive-name: perl/part30
  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 30 (of 36).  If kit 30 is complete, the line"
  21. echo '"'"End of kit 30 (of 36)"'" will echo at the end.'
  22. echo ""
  23. export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
  24. mkdir eg eg/scan lib msdos os2 t t/op x2p 2>/dev/null
  25. echo Extracting os2/os2.c
  26. sed >os2/os2.c <<'!STUFFY!FUNK!' -e 's/X//'
  27. X/* $Header: os2.c,v 4.0 91/03/20 01:36:21 lwall Locked $
  28. X *
  29. X *    (C) Copyright 1989, 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:    os2.c,v $
  35. X * Revision 4.0  91/03/20  01:36:21  lwall
  36. X * 4.0 baseline.
  37. X * 
  38. X * Revision 3.0.1.2  90/11/10  01:42:38  lwall
  39. X * patch38: more msdos/os2 upgrades
  40. X * 
  41. X * Revision 3.0.1.1  90/10/15  17:49:55  lwall
  42. X * patch29: Initial revision
  43. X * 
  44. X * Revision 3.0.1.1  90/03/27  16:10:41  lwall
  45. X * patch16: MSDOS support
  46. X *
  47. X * Revision 1.1  90/03/18  20:32:01  dds
  48. X * Initial revision
  49. X *
  50. X */
  51. X
  52. X#define INCL_DOS
  53. X#define INCL_NOPM
  54. X#include <os2.h>
  55. X
  56. X/*
  57. X * Various Unix compatibility functions for OS/2
  58. X */
  59. X
  60. X#include <stdio.h>
  61. X#include <errno.h>
  62. X#include <process.h>
  63. X
  64. X#include "EXTERN.h"
  65. X#include "perl.h"
  66. X
  67. X
  68. X/* dummies */
  69. X
  70. Xint ioctl(int handle, unsigned int function, char *data)
  71. X{ return -1; }
  72. X
  73. Xint userinit()
  74. X{ return -1; }
  75. X
  76. Xint syscall()
  77. X{ return -1; }
  78. X
  79. X
  80. X/* extendd chdir() */
  81. X
  82. Xint chdir(char *path)
  83. X{
  84. X  if ( path[0] != 0 && path[1] == ':' )
  85. X    DosSelectDisk(toupper(path[0]) - '@');
  86. X
  87. X  DosChDir(path, 0L);
  88. X}
  89. X
  90. X
  91. X/* priorities */
  92. X
  93. Xint setpriority(int class, int pid, int val)
  94. X{
  95. X  int flag = 0;
  96. X
  97. X  if ( pid < 0 )
  98. X  {
  99. X    flag++;
  100. X    pid = -pid;
  101. X  }
  102. X
  103. X  return DosSetPrty(flag ? PRTYS_PROCESSTREE : PRTYS_PROCESS, class, val, pid);
  104. X}
  105. X
  106. Xint getpriority(int which /* ignored */, int pid)
  107. X{
  108. X  USHORT val;
  109. X
  110. X  if ( DosGetPrty(PRTYS_PROCESS, &val, pid) )
  111. X    return -1;
  112. X  else
  113. X    return val;
  114. X}
  115. X
  116. X
  117. X/* get parent process id */
  118. X
  119. Xint getppid(void)
  120. X{
  121. X  PIDINFO pi;
  122. X
  123. X  DosGetPID(&pi);
  124. X  return pi.pidParent;
  125. X}
  126. X
  127. X
  128. X/* kill */
  129. X
  130. Xint kill(int pid, int sig)
  131. X{
  132. X  int flag = 0;
  133. X
  134. X  if ( pid < 0 )
  135. X  {
  136. X    flag++;
  137. X    pid = -pid;
  138. X  }
  139. X
  140. X  switch ( sig & 3 )
  141. X  {
  142. X
  143. X  case 0:
  144. X    DosKillProcess(flag ? DKP_PROCESSTREE : DKP_PROCESS, pid);
  145. X    break;
  146. X
  147. X  case 1: /* FLAG A */
  148. X    DosFlagProcess(pid, flag ? FLGP_SUBTREE : FLGP_PID, PFLG_A, 0);
  149. X    break;
  150. X
  151. X  case 2: /* FLAG B */
  152. X    DosFlagProcess(pid, flag ? FLGP_SUBTREE : FLGP_PID, PFLG_B, 0);
  153. X    break;
  154. X
  155. X  case 3: /* FLAG C */
  156. X    DosFlagProcess(pid, flag ? FLGP_SUBTREE : FLGP_PID, PFLG_C, 0);
  157. X    break;
  158. X
  159. X  }
  160. X}
  161. X
  162. X
  163. X/* Sleep function. */
  164. Xvoid
  165. Xsleep(unsigned len)
  166. X{
  167. X   DosSleep(len * 1000L);
  168. X}
  169. X
  170. X/* Just pretend that everyone is a superuser */
  171. X
  172. Xint setuid()
  173. X{ return 0; }
  174. X
  175. Xint setgid()
  176. X{ return 0; }
  177. X
  178. Xint getuid(void)
  179. X{ return 0; }
  180. X
  181. Xint geteuid(void)
  182. X{ return 0; }
  183. X
  184. Xint getgid(void)
  185. X{ return 0; }
  186. X
  187. Xint getegid(void)
  188. X{ return 0; }
  189. X
  190. X/*
  191. X * The following code is based on the do_exec and do_aexec functions
  192. X * in file doio.c
  193. X */
  194. Xint
  195. Xdo_aspawn(really,arglast)
  196. XSTR *really;
  197. Xint *arglast;
  198. X{
  199. X    register STR **st = stack->ary_array;
  200. X    register int sp = arglast[1];
  201. X    register int items = arglast[2] - sp;
  202. X    register char **a;
  203. X    char **argv;
  204. X    char *tmps;
  205. X    int status;
  206. X
  207. X    if (items) {
  208. X    New(1101,argv, items+1, char*);
  209. X    a = argv;
  210. X    for (st += ++sp; items > 0; items--,st++) {
  211. X        if (*st)
  212. X        *a++ = str_get(*st);
  213. X        else
  214. X        *a++ = "";
  215. X    }
  216. X    *a = Nullch;
  217. X    if (really && *(tmps = str_get(really)))
  218. X        status = spawnvp(P_WAIT,tmps,argv);
  219. X    else
  220. X        status = spawnvp(P_WAIT,argv[0],argv);
  221. X    Safefree(argv);
  222. X    }
  223. X    return status;
  224. X}
  225. X
  226. Xchar *getenv(char *name);
  227. X
  228. Xint
  229. Xdo_spawn(cmd)
  230. Xchar *cmd;
  231. X{
  232. X    register char **a;
  233. X    register char *s;
  234. X    char **argv;
  235. X    char flags[10];
  236. X    int status;
  237. X    char *shell, *cmd2;
  238. X
  239. X    /* save an extra exec if possible */
  240. X    if ((shell = getenv("COMSPEC")) == 0)
  241. X    shell = "C:\\OS2\\CMD.EXE";
  242. X
  243. X    /* see if there are shell metacharacters in it */
  244. X    if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|')
  245. X        || strchr(cmd, '&') || strchr(cmd, '^'))
  246. X      doshell:
  247. X        return spawnl(P_WAIT,shell,shell,"/C",cmd,(char*)0);
  248. X
  249. X    New(1102,argv, strlen(cmd) / 2 + 2, char*);
  250. X
  251. X    New(1103,cmd2, strlen(cmd) + 1, char);
  252. X    strcpy(cmd2, cmd);
  253. X    a = argv;
  254. X    for (s = cmd2; *s;) {
  255. X    while (*s && isspace(*s)) s++;
  256. X    if (*s)
  257. X        *(a++) = s;
  258. X    while (*s && !isspace(*s)) s++;
  259. X    if (*s)
  260. X        *s++ = '\0';
  261. X    }
  262. X    *a = Nullch;
  263. X    if (argv[0])
  264. X    if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
  265. X        Safefree(argv);
  266. X        Safefree(cmd2);
  267. X        goto doshell;
  268. X    }
  269. X    Safefree(cmd2);
  270. X    Safefree(argv);
  271. X    return status;
  272. X}
  273. X
  274. Xusage(char *myname)
  275. X{
  276. X#ifdef MSDOS
  277. X  printf("\nUsage: %s [-acdnpsSvw] [-0[octal]] [-Dnumber] [-i[extension]] [-Idirectory]"
  278. X#else
  279. X  printf("\nUsage: %s [-acdnpPsSuUvw] [-Dnumber] [-i[extension]] [-Idirectory]"
  280. X#endif
  281. X         "\n            [-e \"command\"] [-x[directory]] [filename] [arguments]\n", myname);
  282. X
  283. X  printf("\n  -a  autosplit mode with -n or -p"
  284. X         "\n  -c  syntaxcheck only"
  285. X         "\n  -d  run scripts under debugger"
  286. X         "\n  -n  assume 'while (<>) { ...script... }' loop arround your script"
  287. X         "\n  -p  assume loop like -n but print line also like sed"
  288. X#ifndef MSDOS
  289. X         "\n  -P  run script through C preprocessor befor compilation"
  290. X#endif
  291. X         "\n  -s  enable some switch parsing for switches after script name"
  292. X         "\n  -S  look for the script using PATH environment variable");
  293. X#ifndef MSDOS
  294. X  printf("\n  -u  dump core after compiling the script"
  295. X         "\n  -U  allow unsafe operations");
  296. X#endif
  297. X  printf("\n  -v  print version number and patchlevel of perl"
  298. X         "\n  -w  turn warnings on for compilation of your script\n"
  299. X         "\n  -0[octal]       specify record separator (0, if no argument)"
  300. X         "\n  -Dnumber        set debugging flags (argument is a bit mask)"
  301. X         "\n  -i[extension]   edit <> files in place (make backup if extension supplied)"
  302. X         "\n  -Idirectory     specify include directory in conjunction with -P"
  303. X         "\n  -e command      one line of script, multiple -e options are allowed"
  304. X         "\n                  [filename] can be ommitted, when -e is used"
  305. X         "\n  -x[directory]   strip off text before #!perl line and perhaps cd to directory\n");
  306. X}
  307. !STUFFY!FUNK!
  308. echo Extracting lib/syslog.pl
  309. sed >lib/syslog.pl <<'!STUFFY!FUNK!' -e 's/X//'
  310. X#
  311. X# syslog.pl
  312. X#
  313. X# $Log:    syslog.pl,v $
  314. X# Revision 4.0  91/03/20  01:26:24  lwall
  315. X# 4.0 baseline.
  316. X# 
  317. X# Revision 3.0.1.4  90/11/10  01:41:11  lwall
  318. X# patch38: syslog.pl was referencing an absolute path
  319. X# 
  320. X# Revision 3.0.1.3  90/10/15  17:42:18  lwall
  321. X# patch29: various portability fixes
  322. X# 
  323. X# Revision 3.0.1.1  90/08/09  03:57:17  lwall
  324. X# patch19: Initial revision
  325. X# 
  326. X# Revision 1.2  90/06/11  18:45:30  18:45:30  root ()
  327. X# - Changed 'warn' to 'mail|warning' in test call (to give example of
  328. X#   facility specification, and because 'warn' didn't work on HP-UX).
  329. X# - Fixed typo in &openlog ("ncons" should be "cons").
  330. X# - Added (package-global) $maskpri, and &setlogmask.
  331. X# - In &syslog:
  332. X#   - put argument test ahead of &connect (why waste cycles?),
  333. X#   - allowed facility to be specified in &syslog's first arg (temporarily
  334. X#     overrides any $facility set in &openlog), just as in syslog(3C),
  335. X#   - do a return 0 when bit for $numpri not set in log mask (see syslog(3C)),
  336. X#   - changed $whoami code to use getlogin, getpwuid($<) and 'syslog'
  337. X#     (in that order) when $ident is null,
  338. X#   - made PID logging consistent with syslog(3C) and subject to $lo_pid only,
  339. X#   - fixed typo in "print CONS" statement ($<facility should be <$facility).
  340. X#   - changed \n to \r in print CONS (\r is useful, $message already has a \n).
  341. X# - Changed &xlate to return -1 for an unknown name, instead of croaking.
  342. X# 
  343. X#
  344. X# tom christiansen <tchrist@convex.com>
  345. X# modified to use sockets by Larry Wall <lwall@jpl-devvax.jpl.nasa.gov>
  346. X# NOTE: openlog now takes three arguments, just like openlog(3)
  347. X#
  348. X# call syslog() with a string priority and a list of printf() args
  349. X# like syslog(3)
  350. X#
  351. X#  usage: require 'syslog.pl';
  352. X#
  353. X#  then (put these all in a script to test function)
  354. X#        
  355. X#
  356. X#    do openlog($program,'cons,pid','user');
  357. X#    do syslog('info','this is another test');
  358. X#    do syslog('mail|warning','this is a better test: %d', time);
  359. X#    do closelog();
  360. X#    
  361. X#    do syslog('debug','this is the last test');
  362. X#    do openlog("$program $$",'ndelay','user');
  363. X#    do syslog('notice','fooprogram: this is really done');
  364. X#
  365. X#    $! = 55;
  366. X#    do syslog('info','problem was %m'); # %m == $! in syslog(3)
  367. X
  368. Xpackage syslog;
  369. X
  370. X$host = 'localhost' unless $host;    # set $syslog'host to change
  371. X
  372. Xrequire 'syslog.ph';
  373. X
  374. X$maskpri = &LOG_UPTO(&LOG_DEBUG);
  375. X
  376. Xsub main'openlog {
  377. X    ($ident, $logopt, $facility) = @_;  # package vars
  378. X    $lo_pid = $logopt =~ /\bpid\b/;
  379. X    $lo_ndelay = $logopt =~ /\bndelay\b/;
  380. X    $lo_cons = $logopt =~ /\bcons\b/;
  381. X    $lo_nowait = $logopt =~ /\bnowait\b/;
  382. X    &connect if $lo_ndelay;
  383. X} 
  384. X
  385. Xsub main'closelog {
  386. X    $facility = $ident = '';
  387. X    &disconnect;
  388. X} 
  389. X
  390. Xsub main'setlogmask {
  391. X    local($oldmask) = $maskpri;
  392. X    $maskpri = shift;
  393. X    $oldmask;
  394. X}
  395. Xsub main'syslog {
  396. X    local($priority) = shift;
  397. X    local($mask) = shift;
  398. X    local($message, $whoami);
  399. X    local(@words, $num, $numpri, $numfac, $sum);
  400. X    local($facility) = $facility;    # may need to change temporarily.
  401. X
  402. X    die "syslog: expected both priority and mask" unless $mask && $priority;
  403. X
  404. X    @words = split(/\W+/, $priority, 2);# Allow "level" or "level|facility".
  405. X    undef $numpri;
  406. X    undef $numfac;
  407. X    foreach (@words) {
  408. X    $num = &xlate($_);        # Translate word to number.
  409. X    if (/^kern$/ || $num < 0) {
  410. X        die "syslog: invalid level/facility: $_\n";
  411. X    }
  412. X    elsif ($num <= &LOG_PRIMASK) {
  413. X        die "syslog: too many levels given: $_\n" if defined($numpri);
  414. X        $numpri = $num;
  415. X        return 0 unless &LOG_MASK($numpri) & $maskpri;
  416. X    }
  417. X    else {
  418. X        die "syslog: too many facilities given: $_\n" if defined($numfac);
  419. X        $facility = $_;
  420. X        $numfac = $num;
  421. X    }
  422. X    }
  423. X
  424. X    die "syslog: level must be given\n" unless defined($numpri);
  425. X
  426. X    if (!defined($numfac)) {    # Facility not specified in this call.
  427. X    $facility = 'user' unless $facility;
  428. X    $numfac = &xlate($facility);
  429. X    }
  430. X
  431. X    &connect unless $connected;
  432. X
  433. X    $whoami = $ident;
  434. X
  435. X    if (!$ident && $mask =~ /^(\S.*):\s?(.*)/) {
  436. X    $whoami = $1;
  437. X    $mask = $2;
  438. X    } 
  439. X
  440. X    unless ($whoami) {
  441. X    ($whoami = getlogin) ||
  442. X        ($whoami = getpwuid($<)) ||
  443. X        ($whoami = 'syslog');
  444. X    }
  445. X
  446. X    $whoami .= "[$$]" if $lo_pid;
  447. X
  448. X    $mask =~ s/%m/$!/g;
  449. X    $mask .= "\n" unless $mask =~ /\n$/;
  450. X    $message = sprintf ($mask, @_);
  451. X
  452. X    $sum = $numpri + $numfac;
  453. X    unless (send(SYSLOG,"<$sum>$whoami: $message",0)) {
  454. X    if ($lo_cons) {
  455. X        if ($pid = fork) {
  456. X        unless ($lo_nowait) {
  457. X            do {$died = wait;} until $died == $pid || $died < 0;
  458. X        }
  459. X        }
  460. X        else {
  461. X        open(CONS,">/dev/console");
  462. X        print CONS "<$facility.$priority>$whoami: $message\r";
  463. X        exit if defined $pid;        # if fork failed, we're parent
  464. X        close CONS;
  465. X        }
  466. X    }
  467. X    }
  468. X}
  469. X
  470. Xsub xlate {
  471. X    local($name) = @_;
  472. X    $name =~ y/a-z/A-Z/;
  473. X    $name = "LOG_$name" unless $name =~ /^LOG_/;
  474. X    $name = "syslog'$name";
  475. X    eval &$name || -1;
  476. X}
  477. X
  478. Xsub connect {
  479. X    $pat = 'S n C4 x8';
  480. X
  481. X    $af_unix = 1;
  482. X    $af_inet = 2;
  483. X
  484. X    $stream = 1;
  485. X    $datagram = 2;
  486. X
  487. X    ($name,$aliases,$proto) = getprotobyname('udp');
  488. X    $udp = $proto;
  489. X
  490. X    ($name,$aliase,$port,$proto) = getservbyname('syslog','udp');
  491. X    $syslog = $port;
  492. X
  493. X    if (chop($myname = `hostname`)) {
  494. X    ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($myname);
  495. X    die "Can't lookup $myname\n" unless $name;
  496. X    @bytes = unpack("C4",$addrs[0]);
  497. X    }
  498. X    else {
  499. X    @bytes = (0,0,0,0);
  500. X    }
  501. X    $this = pack($pat, $af_inet, 0, @bytes);
  502. X
  503. X    if ($host =~ /^\d+\./) {
  504. X    @bytes = split(/\./,$host);
  505. X    }
  506. X    else {
  507. X    ($name,$aliases,$addrtype,$length,@addrs) = gethostbyname($host);
  508. X    die "Can't lookup $host\n" unless $name;
  509. X    @bytes = unpack("C4",$addrs[0]);
  510. X    }
  511. X    $that = pack($pat,$af_inet,$syslog,@bytes);
  512. X
  513. X    socket(SYSLOG,$af_inet,$datagram,$udp) || die "socket: $!\n";
  514. X    bind(SYSLOG,$this) || die "bind: $!\n";
  515. X    connect(SYSLOG,$that) || die "connect: $!\n";
  516. X
  517. X    local($old) = select(SYSLOG); $| = 1; select($old);
  518. X    $connected = 1;
  519. X}
  520. X
  521. Xsub disconnect {
  522. X    close SYSLOG;
  523. X    $connected = 0;
  524. X}
  525. X
  526. X1;
  527. !STUFFY!FUNK!
  528. echo Extracting array.c
  529. sed >array.c <<'!STUFFY!FUNK!' -e 's/X//'
  530. X/* $Header: array.c,v 4.0 91/03/20 01:03:32 lwall Locked $
  531. X *
  532. X *    Copyright (c) 1989, Larry Wall
  533. X *
  534. X *    You may distribute under the terms of the GNU General Public License
  535. X *    as specified in the README file that comes with the perl 3.0 kit.
  536. X *
  537. X * $Log:    array.c,v $
  538. X * Revision 4.0  91/03/20  01:03:32  lwall
  539. X * 4.0 baseline.
  540. X * 
  541. X */
  542. X
  543. X#include "EXTERN.h"
  544. X#include "perl.h"
  545. X
  546. XSTR *
  547. Xafetch(ar,key,lval)
  548. Xregister ARRAY *ar;
  549. Xint key;
  550. Xint lval;
  551. X{
  552. X    STR *str;
  553. X
  554. X    if (key < 0 || key > ar->ary_fill) {
  555. X    if (lval && key >= 0) {
  556. X        if (ar->ary_flags & ARF_REAL)
  557. X        str = Str_new(5,0);
  558. X        else
  559. X        str = str_mortal(&str_undef);
  560. X        (void)astore(ar,key,str);
  561. X        return str;
  562. X    }
  563. X    else
  564. X        return &str_undef;
  565. X    }
  566. X    if (!ar->ary_array[key]) {
  567. X    if (lval) {
  568. X        str = Str_new(6,0);
  569. X        (void)astore(ar,key,str);
  570. X        return str;
  571. X    }
  572. X    return &str_undef;
  573. X    }
  574. X    return ar->ary_array[key];
  575. X}
  576. X
  577. Xbool
  578. Xastore(ar,key,val)
  579. Xregister ARRAY *ar;
  580. Xint key;
  581. XSTR *val;
  582. X{
  583. X    int retval;
  584. X
  585. X    if (key < 0)
  586. X    return FALSE;
  587. X    if (key > ar->ary_max) {
  588. X    int newmax;
  589. X
  590. X    if (ar->ary_alloc != ar->ary_array) {
  591. X        retval = ar->ary_array - ar->ary_alloc;
  592. X        Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
  593. X        Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
  594. X        ar->ary_max += retval;
  595. X        ar->ary_array -= retval;
  596. X        if (key > ar->ary_max - 10) {
  597. X        newmax = key + ar->ary_max;
  598. X        goto resize;
  599. X        }
  600. X    }
  601. X    else {
  602. X        if (ar->ary_alloc) {
  603. X        newmax = key + ar->ary_max / 5;
  604. X          resize:
  605. X        Renew(ar->ary_alloc,newmax+1, STR*);
  606. X        Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
  607. X        }
  608. X        else {
  609. X        newmax = key < 4 ? 4 : key;
  610. X        Newz(2,ar->ary_alloc, newmax+1, STR*);
  611. X        }
  612. X        ar->ary_array = ar->ary_alloc;
  613. X        ar->ary_max = newmax;
  614. X    }
  615. X    }
  616. X    if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) {
  617. X    while (++ar->ary_fill < key) {
  618. X        if (ar->ary_array[ar->ary_fill] != Nullstr) {
  619. X        str_free(ar->ary_array[ar->ary_fill]);
  620. X        ar->ary_array[ar->ary_fill] = Nullstr;
  621. X        }
  622. X    }
  623. X    }
  624. X    retval = (ar->ary_array[key] != Nullstr);
  625. X    if (retval && (ar->ary_flags & ARF_REAL))
  626. X    str_free(ar->ary_array[key]);
  627. X    ar->ary_array[key] = val;
  628. X    return retval;
  629. X}
  630. X
  631. XARRAY *
  632. Xanew(stab)
  633. XSTAB *stab;
  634. X{
  635. X    register ARRAY *ar;
  636. X
  637. X    New(1,ar,1,ARRAY);
  638. X    ar->ary_magic = Str_new(7,0);
  639. X    ar->ary_alloc = ar->ary_array = 0;
  640. X    str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  641. X    ar->ary_max = ar->ary_fill = -1;
  642. X    ar->ary_flags = ARF_REAL;
  643. X    return ar;
  644. X}
  645. X
  646. XARRAY *
  647. Xafake(stab,size,strp)
  648. XSTAB *stab;
  649. Xregister int size;
  650. Xregister STR **strp;
  651. X{
  652. X    register ARRAY *ar;
  653. X
  654. X    New(3,ar,1,ARRAY);
  655. X    New(4,ar->ary_alloc,size+1,STR*);
  656. X    Copy(strp,ar->ary_alloc,size,STR*);
  657. X    ar->ary_array = ar->ary_alloc;
  658. X    ar->ary_magic = Str_new(8,0);
  659. X    str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  660. X    ar->ary_fill = size - 1;
  661. X    ar->ary_max = size - 1;
  662. X    ar->ary_flags = 0;
  663. X    while (size--) {
  664. X    (*strp++)->str_pok &= ~SP_TEMP;
  665. X    }
  666. X    return ar;
  667. X}
  668. X
  669. Xvoid
  670. Xaclear(ar)
  671. Xregister ARRAY *ar;
  672. X{
  673. X    register int key;
  674. X
  675. X    if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
  676. X    return;
  677. X    if (key = ar->ary_array - ar->ary_alloc) {
  678. X    ar->ary_max += key;
  679. X    ar->ary_array -= key;
  680. X    }
  681. X    for (key = 0; key <= ar->ary_max; key++)
  682. X    str_free(ar->ary_array[key]);
  683. X    ar->ary_fill = -1;
  684. X    Zero(ar->ary_array, ar->ary_max+1, STR*);
  685. X}
  686. X
  687. Xvoid
  688. Xafree(ar)
  689. Xregister ARRAY *ar;
  690. X{
  691. X    register int key;
  692. X
  693. X    if (!ar)
  694. X    return;
  695. X    if (key = ar->ary_array - ar->ary_alloc) {
  696. X    ar->ary_max += key;
  697. X    ar->ary_array -= key;
  698. X    }
  699. X    if (ar->ary_flags & ARF_REAL) {
  700. X    for (key = 0; key <= ar->ary_max; key++)
  701. X        str_free(ar->ary_array[key]);
  702. X    }
  703. X    str_free(ar->ary_magic);
  704. X    Safefree(ar->ary_alloc);
  705. X    Safefree(ar);
  706. X}
  707. X
  708. Xbool
  709. Xapush(ar,val)
  710. Xregister ARRAY *ar;
  711. XSTR *val;
  712. X{
  713. X    return astore(ar,++(ar->ary_fill),val);
  714. X}
  715. X
  716. XSTR *
  717. Xapop(ar)
  718. Xregister ARRAY *ar;
  719. X{
  720. X    STR *retval;
  721. X
  722. X    if (ar->ary_fill < 0)
  723. X    return Nullstr;
  724. X    retval = ar->ary_array[ar->ary_fill];
  725. X    ar->ary_array[ar->ary_fill--] = Nullstr;
  726. X    return retval;
  727. X}
  728. X
  729. Xaunshift(ar,num)
  730. Xregister ARRAY *ar;
  731. Xregister int num;
  732. X{
  733. X    register int i;
  734. X    register STR **sstr,**dstr;
  735. X
  736. X    if (num <= 0)
  737. X    return;
  738. X    if (ar->ary_array - ar->ary_alloc >= num) {
  739. X    ar->ary_max += num;
  740. X    ar->ary_fill += num;
  741. X    while (num--)
  742. X        *--ar->ary_array = Nullstr;
  743. X    }
  744. X    else {
  745. X    (void)astore(ar,ar->ary_fill+num,(STR*)0);    /* maybe extend array */
  746. X    dstr = ar->ary_array + ar->ary_fill;
  747. X    sstr = dstr - num;
  748. X#ifdef BUGGY_MSC5
  749. X # pragma loop_opt(off)    /* don't loop-optimize the following code */
  750. X#endif /* BUGGY_MSC5 */
  751. X    for (i = ar->ary_fill; i >= 0; i--) {
  752. X        *dstr-- = *sstr--;
  753. X#ifdef BUGGY_MSC5
  754. X # pragma loop_opt()    /* loop-optimization back to command-line setting */
  755. X#endif /* BUGGY_MSC5 */
  756. X    }
  757. X    Zero(ar->ary_array, num, STR*);
  758. X    }
  759. X}
  760. X
  761. XSTR *
  762. Xashift(ar)
  763. Xregister ARRAY *ar;
  764. X{
  765. X    STR *retval;
  766. X
  767. X    if (ar->ary_fill < 0)
  768. X    return Nullstr;
  769. X    retval = *ar->ary_array;
  770. X    *(ar->ary_array++) = Nullstr;
  771. X    ar->ary_max--;
  772. X    ar->ary_fill--;
  773. X    return retval;
  774. X}
  775. X
  776. Xint
  777. Xalen(ar)
  778. Xregister ARRAY *ar;
  779. X{
  780. X    return ar->ary_fill;
  781. X}
  782. X
  783. Xafill(ar, fill)
  784. Xregister ARRAY *ar;
  785. Xint fill;
  786. X{
  787. X    if (fill < 0)
  788. X    fill = -1;
  789. X    if (fill <= ar->ary_max)
  790. X    ar->ary_fill = fill;
  791. X    else
  792. X    (void)astore(ar,fill,Nullstr);
  793. X}
  794. !STUFFY!FUNK!
  795. echo Extracting t/op/stat.t
  796. sed >t/op/stat.t <<'!STUFFY!FUNK!' -e 's/X//'
  797. X#!./perl
  798. X
  799. X# $Header: stat.t,v 4.0 91/03/20 01:54:55 lwall Locked $
  800. X
  801. Xprint "1..56\n";
  802. X
  803. Xchop($cwd = `pwd`);
  804. X
  805. Xunlink "Op.stat.tmp";
  806. Xopen(foo, ">Op.stat.tmp");
  807. X
  808. X($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  809. X    $blksize,$blocks) = stat(foo);
  810. Xif ($nlink == 1) {print "ok 1\n";} else {print "not ok 1\n";}
  811. Xif ($mtime && $mtime == $ctime) {print "ok 2\n";} else {print "not ok 2\n";}
  812. X
  813. Xprint foo "Now is the time for all good men to come to.\n";
  814. Xclose(foo);
  815. X
  816. Xsleep 2;
  817. X
  818. X`rm -f Op.stat.tmp2; ln Op.stat.tmp Op.stat.tmp2; chmod 644 Op.stat.tmp`;
  819. X
  820. X($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  821. X    $blksize,$blocks) = stat('Op.stat.tmp');
  822. X
  823. Xif ($nlink == 2) {print "ok 3\n";} else {print "not ok 3\n";}
  824. Xif (($mtime && $mtime != $ctime) || $cwd =~ m#/afs/#) {
  825. X    print "ok 4\n";
  826. X}
  827. Xelse {
  828. X    print "not ok 4\n";
  829. X}
  830. Xprint "#4    :$mtime: != :$ctime:\n";
  831. X
  832. X`cp /dev/null Op.stat.tmp`;
  833. X
  834. Xif (-z 'Op.stat.tmp') {print "ok 5\n";} else {print "not ok 5\n";}
  835. Xif (! -s 'Op.stat.tmp') {print "ok 6\n";} else {print "not ok 6\n";}
  836. X
  837. X`echo hi >Op.stat.tmp`;
  838. Xif (! -z 'Op.stat.tmp') {print "ok 7\n";} else {print "not ok 7\n";}
  839. Xif (-s 'Op.stat.tmp') {print "ok 8\n";} else {print "not ok 8\n";}
  840. X
  841. Xunlink 'Op.stat.tmp';
  842. X$olduid = $>;        # can't test -r if uid == 0
  843. X`echo hi >Op.stat.tmp`;
  844. Xchmod 0,'Op.stat.tmp';
  845. Xeval '$> = 1;';        # so switch uid (may not be implemented)
  846. Xif (!$> || ! -r 'Op.stat.tmp') {print "ok 9\n";} else {print "not ok 9\n";}
  847. Xif (!$> || ! -w 'Op.stat.tmp') {print "ok 10\n";} else {print "not ok 10\n";}
  848. Xeval '$> = $olduid;';        # switch uid back (may not be implemented)
  849. Xprint "# olduid=$olduid, newuid=$>\n" unless ($> == $olduid);
  850. Xif (! -x 'Op.stat.tmp') {print "ok 11\n";} else {print "not ok 11\n";}
  851. X
  852. Xforeach ((12,13,14,15,16,17)) {
  853. X    print "ok $_\n";        #deleted tests
  854. X}
  855. X
  856. Xchmod 0700,'Op.stat.tmp';
  857. Xif (-r 'Op.stat.tmp') {print "ok 18\n";} else {print "not ok 18\n";}
  858. Xif (-w 'Op.stat.tmp') {print "ok 19\n";} else {print "not ok 19\n";}
  859. Xif (-x 'Op.stat.tmp') {print "ok 20\n";} else {print "not ok 20\n";}
  860. X
  861. Xif (-f 'Op.stat.tmp') {print "ok 21\n";} else {print "not ok 21\n";}
  862. Xif (! -d 'Op.stat.tmp') {print "ok 22\n";} else {print "not ok 22\n";}
  863. X
  864. Xif (-d '.') {print "ok 23\n";} else {print "not ok 23\n";}
  865. Xif (! -f '.') {print "ok 24\n";} else {print "not ok 24\n";}
  866. X
  867. Xif (`ls -l perl` =~ /^l.*->/) {
  868. X    if (-l 'perl') {print "ok 25\n";} else {print "not ok 25\n";}
  869. X}
  870. Xelse {
  871. X    print "ok 25\n";
  872. X}
  873. X
  874. Xif (-o 'Op.stat.tmp') {print "ok 26\n";} else {print "not ok 26\n";}
  875. X
  876. Xif (-e 'Op.stat.tmp') {print "ok 27\n";} else {print "not ok 27\n";}
  877. X`rm -f Op.stat.tmp Op.stat.tmp2`;
  878. Xif (! -e 'Op.stat.tmp') {print "ok 28\n";} else {print "not ok 28\n";}
  879. X
  880. Xif (-c '/dev/tty') {print "ok 29\n";} else {print "not ok 29\n";}
  881. Xif (! -c '.') {print "ok 30\n";} else {print "not ok 30\n";}
  882. X
  883. Xif (! -e '/dev/printer' || -c '/dev/printer' || -S '/dev/printer')
  884. X    {print "ok 31\n";}
  885. Xelse
  886. X    {print "not ok 31\n";}
  887. Xif (! -S '.') {print "ok 32\n";} else {print "not ok 32\n";}
  888. X
  889. Xif (! -e '/dev/mt0' || -b '/dev/mt0')
  890. X    {print "ok 33\n";}
  891. Xelse
  892. X    {print "not ok 33\n";}
  893. Xif (! -b '.') {print "ok 34\n";} else {print "not ok 34\n";}
  894. X
  895. X$cnt = $uid = 0;
  896. X
  897. Xdie "Can't run op/stat.t test 35 without pwd working" unless $cwd;
  898. Xchdir '/usr/bin' || die "Can't cd to /usr/bin";
  899. Xwhile (defined($_ = <*>)) {
  900. X    $cnt++;
  901. X    $uid++ if -u;
  902. X    last if $uid && $uid < $cnt;
  903. X}
  904. Xchdir $cwd || die "Can't cd back to $cwd";
  905. X
  906. X# I suppose this is going to fail somewhere...
  907. Xif ($uid > 0 && $uid < $cnt) {print "ok 35\n";} else {print "not ok 35\n";}
  908. X
  909. Xunless (open(tty,"/dev/tty")) {
  910. X    print STDERR "Can't open /dev/tty--run t/TEST outside of make.\n";
  911. X}
  912. Xif (-t tty) {print "ok 36\n";} else {print "not ok 36\n";}
  913. Xif (-c tty) {print "ok 37\n";} else {print "not ok 37\n";}
  914. Xclose(tty);
  915. Xif (! -t tty) {print "ok 38\n";} else {print "not ok 38\n";}
  916. Xopen(null,"/dev/null");
  917. Xif (! -t null || -e '/xenix') {print "ok 39\n";} else {print "not ok 39\n";}
  918. Xclose(null);
  919. Xif (-t) {print "ok 40\n";} else {print "not ok 40\n";}
  920. X
  921. X# These aren't strictly "stat" calls, but so what?
  922. X
  923. Xif (-T 'op/stat.t') {print "ok 41\n";} else {print "not ok 41\n";}
  924. Xif (! -B 'op/stat.t') {print "ok 42\n";} else {print "not ok 42\n";}
  925. X
  926. Xif (-B './perl') {print "ok 43\n";} else {print "not ok 43\n";}
  927. Xif (! -T './perl') {print "ok 44\n";} else {print "not ok 44\n";}
  928. X
  929. Xopen(foo,'op/stat.t');
  930. Xif (-T foo) {print "ok 45\n";} else {print "not ok 45\n";}
  931. Xif (! -B foo) {print "ok 46\n";} else {print "not ok 46\n";}
  932. X$_ = <foo>;
  933. Xif (/perl/) {print "ok 47\n";} else {print "not ok 47\n";}
  934. Xif (-T foo) {print "ok 48\n";} else {print "not ok 48\n";}
  935. Xif (! -B foo) {print "ok 49\n";} else {print "not ok 49\n";}
  936. Xclose(foo);
  937. X
  938. Xopen(foo,'op/stat.t');
  939. X$_ = <foo>;
  940. Xif (/perl/) {print "ok 50\n";} else {print "not ok 50\n";}
  941. Xif (-T foo) {print "ok 51\n";} else {print "not ok 51\n";}
  942. Xif (! -B foo) {print "ok 52\n";} else {print "not ok 52\n";}
  943. Xseek(foo,0,0);
  944. Xif (-T foo) {print "ok 53\n";} else {print "not ok 53\n";}
  945. Xif (! -B foo) {print "ok 54\n";} else {print "not ok 54\n";}
  946. Xclose(foo);
  947. X
  948. Xif (-T '/dev/null') {print "ok 55\n";} else {print "not ok 55\n";}
  949. Xif (-B '/dev/null') {print "ok 56\n";} else {print "not ok 56\n";}
  950. !STUFFY!FUNK!
  951. echo Extracting msdos/msdos.c
  952. sed >msdos/msdos.c <<'!STUFFY!FUNK!' -e 's/X//'
  953. X/* $Header: msdos.c,v 4.0 91/03/20 01:34:46 lwall Locked $
  954. X *
  955. X *    (C) Copyright 1989, 1990 Diomidis Spinellis.
  956. X *
  957. X *    You may distribute under the terms of the GNU General Public License
  958. X *    as specified in the README file that comes with the perl 3.0 kit.
  959. X *
  960. X * $Log:    msdos.c,v $
  961. X * Revision 4.0  91/03/20  01:34:46  lwall
  962. X * 4.0 baseline.
  963. X * 
  964. X * Revision 3.0.1.1  90/03/27  16:10:41  lwall
  965. X * patch16: MSDOS support
  966. X * 
  967. X * Revision 1.1  90/03/18  20:32:01  dds
  968. X * Initial revision
  969. X *
  970. X */
  971. X
  972. X/*
  973. X * Various Unix compatibility functions for MS-DOS.
  974. X */
  975. X
  976. X#include "EXTERN.h"
  977. X#include "perl.h"
  978. X
  979. X#include <dos.h>
  980. X#include <process.h>
  981. X
  982. X/*
  983. X * Interface to the MS-DOS ioctl system call.
  984. X * The function is encoded as follows:
  985. X * The lowest nibble of the function code goes to AL
  986. X * The two middle nibbles go to CL
  987. X * The high nibble goes to CH
  988. X *
  989. X * The return code is -1 in the case of an error and if successful
  990. X * for functions AL = 00, 09, 0a the value of the register DX
  991. X * for functions AL = 02 - 08, 0e the value of the register AX
  992. X * for functions AL = 01, 0b - 0f the number 0
  993. X *
  994. X * Notice that this restricts the ioctl subcodes stored in AL to 00-0f
  995. X * In the Ralf Borwn interrupt list 90.1 there are no subcodes above AL=0f
  996. X * so we are ok.
  997. X * Furthermore CH is also restriced in the same area.  Where CH is used as a
  998. X * code it always is between 00-0f.  In the case where it forms a count
  999. X * together with CL we arbitrarily set the highest count limit to 4095.  It
  1000. X * sounds reasonable for an ioctl.
  1001. X * The other alternative would have been to use the pointer argument to
  1002. X * point the the values of CX.  The problem with this approach is that
  1003. X * of accessing wild regions when DX is used as a number and not as a
  1004. X * pointer.
  1005. X */
  1006. Xint
  1007. Xioctl(int handle, unsigned int function, char *data)
  1008. X{
  1009. X    union REGS      srv;
  1010. X    struct SREGS    segregs;
  1011. X
  1012. X    srv.h.ah = 0x44;
  1013. X    srv.h.al = (unsigned char)(function & 0x0F);
  1014. X    srv.x.bx = handle;
  1015. X    srv.x.cx = function >> 4;
  1016. X    segread(&segregs);
  1017. X#if ( defined(M_I86LM) || defined(M_I86CM) || defined(M_I86HM) )
  1018. X    segregs.ds = FP_SEG(data);
  1019. X    srv.x.dx = FP_OFF(data);
  1020. X#else
  1021. X    srv.x.dx = (unsigned int) data;
  1022. X#endif
  1023. X    intdosx(&srv, &srv, &segregs);
  1024. X    if (srv.x.cflag & 1) {
  1025. X        switch(srv.x.ax ){
  1026. X        case 1:
  1027. X            errno = EINVAL;
  1028. X            break;
  1029. X        case 2:
  1030. X        case 3:
  1031. X            errno = ENOENT;
  1032. X            break;
  1033. X        case 4:
  1034. X            errno = EMFILE;
  1035. X            break;
  1036. X        case 5:
  1037. X            errno = EPERM;
  1038. X            break;
  1039. X        case 6:
  1040. X            errno = EBADF;
  1041. X            break;
  1042. X        case 8:
  1043. X            errno = ENOMEM;
  1044. X            break;
  1045. X        case 0xc:
  1046. X        case 0xd:
  1047. X        case 0xf:
  1048. X            errno = EINVAL;
  1049. X            break;
  1050. X        case 0x11:
  1051. X            errno = EXDEV;
  1052. X            break;
  1053. X        case 0x12:
  1054. X            errno = ENFILE;
  1055. X            break;
  1056. X        default:
  1057. X            errno = EZERO;
  1058. X            break;
  1059. X        }
  1060. X        return -1;
  1061. X    } else {
  1062. X        switch (function & 0xf) {
  1063. X        case 0: case 9: case 0xa:
  1064. X            return srv.x.dx;
  1065. X        case 2: case 3: case 4: case 5:
  1066. X        case 6: case 7: case 8: case 0xe:
  1067. X            return srv.x.ax;
  1068. X        case 1: case 0xb: case 0xc: case 0xd:
  1069. X        case 0xf:
  1070. X        default:
  1071. X            return 0;
  1072. X        }
  1073. X    }
  1074. X}
  1075. X
  1076. X
  1077. X/*
  1078. X * Sleep function.
  1079. X */
  1080. Xvoid
  1081. Xsleep(unsigned len)
  1082. X{
  1083. X    time_t end;
  1084. X
  1085. X    end = time((time_t *)0) + len;
  1086. X    while (time((time_t *)0) < end)
  1087. X        ;
  1088. X}
  1089. X
  1090. X/*
  1091. X * Just pretend that everyone is a superuser
  1092. X */
  1093. X#define ROOT_UID    0
  1094. X#define ROOT_GID    0
  1095. Xint
  1096. Xgetuid(void)
  1097. X{
  1098. X    return ROOT_UID;
  1099. X}
  1100. X
  1101. Xint
  1102. Xgeteuid(void)
  1103. X{
  1104. X    return ROOT_UID;
  1105. X}
  1106. X
  1107. Xint
  1108. Xgetgid(void)
  1109. X{
  1110. X    return ROOT_GID;
  1111. X}
  1112. X
  1113. Xint
  1114. Xgetegid(void)
  1115. X{
  1116. X    return ROOT_GID;
  1117. X}
  1118. X
  1119. Xint
  1120. Xsetuid(int uid)
  1121. X{ return (uid==ROOT_UID?0:-1); }
  1122. X
  1123. Xint
  1124. Xsetgid(int gid)
  1125. X{ return (gid==ROOT_GID?0:-1); }
  1126. X
  1127. X/*
  1128. X * The following code is based on the do_exec and do_aexec functions
  1129. X * in file doio.c
  1130. X */
  1131. Xint
  1132. Xdo_aspawn(really,arglast)
  1133. XSTR *really;
  1134. Xint *arglast;
  1135. X{
  1136. X    register STR **st = stack->ary_array;
  1137. X    register int sp = arglast[1];
  1138. X    register int items = arglast[2] - sp;
  1139. X    register char **a;
  1140. X    char **argv;
  1141. X    char *tmps;
  1142. X    int status;
  1143. X
  1144. X    if (items) {
  1145. X    New(1101,argv, items+1, char*);
  1146. X    a = argv;
  1147. X    for (st += ++sp; items > 0; items--,st++) {
  1148. X        if (*st)
  1149. X        *a++ = str_get(*st);
  1150. X        else
  1151. X        *a++ = "";
  1152. X    }
  1153. X    *a = Nullch;
  1154. X    if (really && *(tmps = str_get(really)))
  1155. X        status = spawnvp(P_WAIT,tmps,argv);
  1156. X    else
  1157. X        status = spawnvp(P_WAIT,argv[0],argv);
  1158. X    Safefree(argv);
  1159. X    }
  1160. X    return status;
  1161. X}
  1162. X
  1163. X
  1164. Xint
  1165. Xdo_spawn(cmd)
  1166. Xchar *cmd;
  1167. X{
  1168. X    register char **a;
  1169. X    register char *s;
  1170. X    char **argv;
  1171. X    char flags[10];
  1172. X    int status;
  1173. X    char *shell, *cmd2;
  1174. X
  1175. X    /* save an extra exec if possible */
  1176. X    if ((shell = getenv("COMSPEC")) == 0)
  1177. X    shell = "\\command.com";
  1178. X
  1179. X    /* see if there are shell metacharacters in it */
  1180. X    if (strchr(cmd, '>') || strchr(cmd, '<') || strchr(cmd, '|'))
  1181. X      doshell:
  1182. X        return spawnl(P_WAIT,shell,shell,"/c",cmd,(char*)0);
  1183. X
  1184. X    New(1102,argv, strlen(cmd) / 2 + 2, char*);
  1185. X
  1186. X    New(1103,cmd2, strlen(cmd) + 1, char);
  1187. X    strcpy(cmd2, cmd);
  1188. X    a = argv;
  1189. X    for (s = cmd2; *s;) {
  1190. X    while (*s && isspace(*s)) s++;
  1191. X    if (*s)
  1192. X        *(a++) = s;
  1193. X    while (*s && !isspace(*s)) s++;
  1194. X    if (*s)
  1195. X        *s++ = '\0';
  1196. X    }
  1197. X    *a = Nullch;
  1198. X    if (argv[0])
  1199. X    if ((status = spawnvp(P_WAIT,argv[0],argv)) == -1) {
  1200. X        Safefree(argv);
  1201. X        Safefree(cmd2);
  1202. X        goto doshell;
  1203. X    }
  1204. X    Safefree(cmd2);
  1205. X    Safefree(argv);
  1206. X    return status;
  1207. X}
  1208. !STUFFY!FUNK!
  1209. echo Extracting eg/scan/scan_messages
  1210. sed >eg/scan/scan_messages <<'!STUFFY!FUNK!' -e 's/X//'
  1211. X#!/usr/bin/perl -P
  1212. X
  1213. X# $Header: scan_messages,v 4.0 91/03/20 01:13:01 lwall Locked $
  1214. X
  1215. X# This prints out extraordinary console messages.  You'll need to customize.
  1216. X
  1217. Xchdir('/usr/adm/private/memories') || die "Can't cd to memories: $!\n";
  1218. X
  1219. X$maxpos = `cat oldmsgs 2>&1`;
  1220. X
  1221. X#if defined(mc300) || defined(mc500) || defined(mc700)
  1222. Xopen(Msgs, '/dev/null') || die "scan_messages: can't open messages";
  1223. X#else
  1224. Xopen(Msgs, '/usr/adm/messages') || die "scan_messages: can't open messages";
  1225. X#endif
  1226. X
  1227. X($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  1228. X   $blksize,$blocks) = stat(Msgs);
  1229. X
  1230. Xif ($size < $maxpos) {        # Did somebody truncate messages file?
  1231. X    $maxpos = 0;
  1232. X}
  1233. X
  1234. Xseek(Msgs,$maxpos,0);        # Start where we left off last time.
  1235. X
  1236. Xwhile (<Msgs>) {
  1237. X    s/\[(\d+)\]/#/ && s/$1/#/g;
  1238. X#ifdef vax
  1239. X    $_ =~ s/[A-Z][a-z][a-z] +\w+ +[0-9:]+ +\w+ +//;
  1240. X    next if /root@.*:/;
  1241. X    next if /^vmunix: 4.3 BSD UNIX/;
  1242. X    next if /^vmunix: Copyright/;
  1243. X    next if /^vmunix: avail mem =/;
  1244. X    next if /^vmunix: SBIA0 at /;
  1245. X    next if /^vmunix: disk ra81 is/;
  1246. X    next if /^vmunix: dmf. at uba/;
  1247. X    next if /^vmunix: dmf.:.*asynch/;
  1248. X    next if /^vmunix: ex. at uba/;
  1249. X    next if /^vmunix: ex.: HW/;
  1250. X    next if /^vmunix: il. at uba/;
  1251. X    next if /^vmunix: il.: hardware/;
  1252. X    next if /^vmunix: ra. at uba/;
  1253. X    next if /^vmunix: ra.: media/;
  1254. X    next if /^vmunix: real mem/;
  1255. X    next if /^vmunix: syncing disks/;
  1256. X    next if /^vmunix: tms/;
  1257. X    next if /^vmunix: tmscp. at uba/;
  1258. X    next if /^vmunix: uba. at /;
  1259. X    next if /^vmunix: uda. at /;
  1260. X    next if /^vmunix: uda.: unit . ONLIN/;
  1261. X    next if /^vmunix: .*buffers containing/;
  1262. X    next if /^syslogd: .*newslog/;
  1263. X#endif
  1264. X    next if /unknown service/;
  1265. X    next if /^\.\.\.$/;
  1266. X    if (/^[A-Z][a-z][a-z] [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]/) {
  1267. X    $pfx = '';
  1268. X    next;
  1269. X    }
  1270. X    next if /^[ \t]*$/;
  1271. X    next if /^[ 0-9]*done$/;
  1272. X    if (/^A/) {
  1273. X    next if /^Accounting [sr]/;
  1274. X    }
  1275. X    elsif (/^C/) {
  1276. X    next if /^Called from/;
  1277. X    next if /^Copyright/;
  1278. X    }
  1279. X    elsif (/^E/) {
  1280. X    next if /^End traceback/;
  1281. X    next if /^Ethernet address =/;
  1282. X    }
  1283. X    elsif (/^K/) {
  1284. X    next if /^KERNEL MODE/;
  1285. X    }
  1286. X    elsif (/^R/) {
  1287. X    next if /^Rebooting Unix/;
  1288. X    }
  1289. X    elsif (/^S/) {
  1290. X    next if /^Sun UNIX 4\.2 Release/;
  1291. X    }
  1292. X    elsif (/^W/) {
  1293. X    next if /^WARNING: clock gained/;
  1294. X    }
  1295. X    elsif (/^a/) {
  1296. X    next if /^arg /;
  1297. X    next if /^avail mem =/;
  1298. X    }
  1299. X    elsif (/^b/) {
  1300. X    next if /^bwtwo[0-9] at /;
  1301. X    }
  1302. X    elsif (/^c/) {
  1303. X    next if /^cgone[0-9] at /;
  1304. X    next if /^cdp[0-9] at /;
  1305. X    next if /^csr /;
  1306. X    }
  1307. X    elsif (/^d/) {
  1308. X    next if /^dcpa: init/;
  1309. X    next if /^done$/;
  1310. X    next if /^dts/;
  1311. X    next if /^dump i\/o error/;
  1312. X    next if /^dumping to dev/;
  1313. X    next if /^dump succeeded/;
  1314. X    $pfx = '*' if /^dev = /;
  1315. X    }
  1316. X    elsif (/^e/) {
  1317. X    next if /^end \*\*/;
  1318. X    next if /^error in copy/;
  1319. X    }
  1320. X    elsif (/^f/) {
  1321. X    next if /^found /;
  1322. X    }
  1323. X    elsif (/^i/) {
  1324. X    next if /^ib[0-9] at /;
  1325. X    next if /^ie[0-9] at /;
  1326. X    }
  1327. X    elsif (/^l/) {
  1328. X    next if /^le[0-9] at /;
  1329. X    }
  1330. X    elsif (/^m/) {
  1331. X    next if /^mem = /;
  1332. X    next if /^mt[0-9] at /;
  1333. X    next if /^mti[0-9] at /;
  1334. X    $pfx = '*' if /^mode = /;
  1335. X    }
  1336. X    elsif (/^n/) {
  1337. X    next if /^not found /;
  1338. X    }
  1339. X    elsif (/^p/) {
  1340. X    next if /^page map /;
  1341. X    next if /^pi[0-9] at /;
  1342. X    $pfx = '*' if /^panic/;
  1343. X    }
  1344. X    elsif (/^q/) {
  1345. X    next if /^qqq /;
  1346. X    }
  1347. X    elsif (/^r/) {
  1348. X    next if /^read  /;
  1349. X    next if /^revarp: Requesting/;
  1350. X    next if /^root [od]/;
  1351. X    }
  1352. X    elsif (/^s/) {
  1353. X    next if /^sc[0-9] at /;
  1354. X    next if /^sd[0-9] at /;
  1355. X    next if /^sd[0-9]: </;
  1356. X    next if /^si[0-9] at /;
  1357. X    next if /^si_getstatus/;
  1358. X    next if /^sk[0-9] at /;
  1359. X    next if /^skioctl/;
  1360. X    next if /^skopen/;
  1361. X    next if /^skprobe/;
  1362. X    next if /^skread/;
  1363. X    next if /^skwrite/;
  1364. X    next if /^sky[0-9] at /;
  1365. X    next if /^st[0-9] at /;
  1366. X    next if /^st0:.*load/;
  1367. X    next if /^stat1 = /;
  1368. X    next if /^syncing disks/;
  1369. X    next if /^syslogd: going down on signal 15/;
  1370. X    }
  1371. X    elsif (/^t/) {
  1372. X    next if /^timeout [0-9]/;
  1373. X    next if /^tm[0-9] at /;
  1374. X    next if /^tod[0-9] at /;
  1375. X    next if /^tv [0-9]/;
  1376. X    $pfx = '*' if /^trap address/;
  1377. X    }
  1378. X    elsif (/^u/) {
  1379. X    next if /^unit nsk/;
  1380. X    next if /^use one of/;
  1381. X    $pfx = '' if /^using/;
  1382. X    next if /^using [0-9]+ buffers/;
  1383. X    }
  1384. X    elsif (/^x/) {
  1385. X    next if /^xy[0-9] at /;
  1386. X    next if /^write [0-9]/;
  1387. X    next if /^xy[0-9]: </;
  1388. X    next if /^xyc[0-9] at /;
  1389. X    }
  1390. X    elsif (/^y/) {
  1391. X    next if /^yyy [0-9]/;
  1392. X    }
  1393. X    elsif (/^z/) {
  1394. X    next if /^zs[0-9] at /;
  1395. X    }
  1396. X    $pfx = '*' if /^[a-z]+:$/;
  1397. X    s/pid [0-9]+: //;
  1398. X    if (/last message repeated ([0-9]+) time/) {
  1399. X    $seen{$last} += $1;
  1400. X    next;
  1401. X    }
  1402. X    s/^/$pfx/ if $pfx;
  1403. X    unless ($seen{$_}++) {
  1404. X    push(@seen,$_);
  1405. X    }
  1406. X    $last = $_;
  1407. X}
  1408. X$max = tell(Msgs);
  1409. X
  1410. Xopen(tmp,'|sort >oldmsgs.tmp') || die "Can't create tmp file: $!\n";
  1411. Xwhile ($_ = pop(@seen)) {
  1412. X    print tmp $_;
  1413. X}
  1414. Xclose(tmp);
  1415. Xopen(tmp,'oldmsgs.tmp') || die "Can't reopen tmp file: $!\n";
  1416. Xwhile (<tmp>) {
  1417. X    if (/^nd:/) {
  1418. X    next if $seen{$_} < 20;
  1419. X    }
  1420. X    if (/NFS/) {
  1421. X    next if $seen{$_} < 20;
  1422. X    }
  1423. X    if (/no carrier/) {
  1424. X    next if $seen{$_} < 20;
  1425. X    }
  1426. X    if (/silo overflow/) {
  1427. X    next if $seen{$_} < 20;
  1428. X    }
  1429. X    print $seen{$_},":\t",$_;
  1430. X}
  1431. X
  1432. Xprint `rm -f oldmsgs.tmp 2>&1; echo $max > oldmsgs 2>&1`;
  1433. !STUFFY!FUNK!
  1434. echo Extracting x2p/util.c
  1435. sed >x2p/util.c <<'!STUFFY!FUNK!' -e 's/X//'
  1436. X/* $Header: util.c,v 4.0 91/03/20 01:58:25 lwall Locked $
  1437. X *
  1438. X *    Copyright (c) 1989, Larry Wall
  1439. X *
  1440. X *    You may distribute under the terms of the GNU General Public License
  1441. X *    as specified in the README file that comes with the perl 3.0 kit.
  1442. X *
  1443. X * $Log:    util.c,v $
  1444. X * Revision 4.0  91/03/20  01:58:25  lwall
  1445. X * 4.0 baseline.
  1446. X * 
  1447. X */
  1448. X
  1449. X#include <stdio.h>
  1450. X
  1451. X#include "handy.h"
  1452. X#include "EXTERN.h"
  1453. X#include "a2p.h"
  1454. X#include "INTERN.h"
  1455. X#include "util.h"
  1456. X
  1457. X#define FLUSH
  1458. X#define MEM_SIZE unsigned int
  1459. X
  1460. Xstatic char nomem[] = "Out of memory!\n";
  1461. X
  1462. X/* paranoid version of malloc */
  1463. X
  1464. Xstatic int an = 0;
  1465. X
  1466. Xchar *
  1467. Xsafemalloc(size)
  1468. XMEM_SIZE size;
  1469. X{
  1470. X    char *ptr;
  1471. X    char *malloc();
  1472. X
  1473. X    ptr = malloc(size?size:1);    /* malloc(0) is NASTY on our system */
  1474. X#ifdef DEBUGGING
  1475. X    if (debug & 128)
  1476. X    fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
  1477. X#endif
  1478. X    if (ptr != Nullch)
  1479. X    return ptr;
  1480. X    else {
  1481. X    fputs(nomem,stdout) FLUSH;
  1482. X    exit(1);
  1483. X    }
  1484. X    /*NOTREACHED*/
  1485. X}
  1486. X
  1487. X/* paranoid version of realloc */
  1488. X
  1489. Xchar *
  1490. Xsaferealloc(where,size)
  1491. Xchar *where;
  1492. XMEM_SIZE size;
  1493. X{
  1494. X    char *ptr;
  1495. X    char *realloc();
  1496. X
  1497. X    ptr = realloc(where,size?size:1);    /* realloc(0) is NASTY on our system */
  1498. X#ifdef DEBUGGING
  1499. X    if (debug & 128) {
  1500. X    fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
  1501. X    fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
  1502. X    }
  1503. X#endif
  1504. X    if (ptr != Nullch)
  1505. X    return ptr;
  1506. X    else {
  1507. X    fputs(nomem,stdout) FLUSH;
  1508. X    exit(1);
  1509. X    }
  1510. X    /*NOTREACHED*/
  1511. X}
  1512. X
  1513. X/* safe version of free */
  1514. X
  1515. Xsafefree(where)
  1516. Xchar *where;
  1517. X{
  1518. X#ifdef DEBUGGING
  1519. X    if (debug & 128)
  1520. X    fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
  1521. X#endif
  1522. X    free(where);
  1523. X}
  1524. X
  1525. X/* safe version of string copy */
  1526. X
  1527. Xchar *
  1528. Xsafecpy(to,from,len)
  1529. Xchar *to;
  1530. Xregister char *from;
  1531. Xregister int len;
  1532. X{
  1533. X    register char *dest = to;
  1534. X
  1535. X    if (from != Nullch) 
  1536. X    for (len--; len && (*dest++ = *from++); len--) ;
  1537. X    *dest = '\0';
  1538. X    return to;
  1539. X}
  1540. X
  1541. X/* copy a string up to some (non-backslashed) delimiter, if any */
  1542. X
  1543. Xchar *
  1544. Xcpytill(to,from,delim)
  1545. Xregister char *to, *from;
  1546. Xregister int delim;
  1547. X{
  1548. X    for (; *from; from++,to++) {
  1549. X    if (*from == '\\') {
  1550. X        if (from[1] == delim)
  1551. X        from++;
  1552. X        else if (from[1] == '\\')
  1553. X        *to++ = *from++;
  1554. X    }
  1555. X    else if (*from == delim)
  1556. X        break;
  1557. X    *to = *from;
  1558. X    }
  1559. X    *to = '\0';
  1560. X    return from;
  1561. X}
  1562. X
  1563. X
  1564. Xchar *
  1565. Xcpy2(to,from,delim)
  1566. Xregister char *to, *from;
  1567. Xregister int delim;
  1568. X{
  1569. X    for (; *from; from++,to++) {
  1570. X    if (*from == '\\')
  1571. X        *to++ = *from++;
  1572. X    else if (*from == '$')
  1573. X        *to++ = '\\';
  1574. X    else if (*from == delim)
  1575. X        break;
  1576. X    *to = *from;
  1577. X    }
  1578. X    *to = '\0';
  1579. X    return from;
  1580. X}
  1581. X
  1582. X/* return ptr to little string in big string, NULL if not found */
  1583. X
  1584. Xchar *
  1585. Xinstr(big, little)
  1586. Xchar *big, *little;
  1587. X
  1588. X{
  1589. X    register char *t, *s, *x;
  1590. X
  1591. X    for (t = big; *t; t++) {
  1592. X    for (x=t,s=little; *s; x++,s++) {
  1593. X        if (!*x)
  1594. X        return Nullch;
  1595. X        if (*s != *x)
  1596. X        break;
  1597. X    }
  1598. X    if (!*s)
  1599. X        return t;
  1600. X    }
  1601. X    return Nullch;
  1602. X}
  1603. X
  1604. X/* copy a string to a safe spot */
  1605. X
  1606. Xchar *
  1607. Xsavestr(str)
  1608. Xchar *str;
  1609. X{
  1610. X    register char *newaddr = safemalloc((MEM_SIZE)(strlen(str)+1));
  1611. X
  1612. X    (void)strcpy(newaddr,str);
  1613. X    return newaddr;
  1614. X}
  1615. X
  1616. X/* grow a static string to at least a certain length */
  1617. X
  1618. Xvoid
  1619. Xgrowstr(strptr,curlen,newlen)
  1620. Xchar **strptr;
  1621. Xint *curlen;
  1622. Xint newlen;
  1623. X{
  1624. X    if (newlen > *curlen) {        /* need more room? */
  1625. X    if (*curlen)
  1626. X        *strptr = saferealloc(*strptr,(MEM_SIZE)newlen);
  1627. X    else
  1628. X        *strptr = safemalloc((MEM_SIZE)newlen);
  1629. X    *curlen = newlen;
  1630. X    }
  1631. X}
  1632. X
  1633. X/*VARARGS1*/
  1634. Xfatal(pat,a1,a2,a3,a4)
  1635. Xchar *pat;
  1636. X{
  1637. X    fprintf(stderr,pat,a1,a2,a3,a4);
  1638. X    exit(1);
  1639. X}
  1640. X
  1641. X/*VARARGS1*/
  1642. Xwarn(pat,a1,a2,a3,a4)
  1643. Xchar *pat;
  1644. X{
  1645. X    fprintf(stderr,pat,a1,a2,a3,a4);
  1646. X}
  1647. X
  1648. Xstatic bool firstsetenv = TRUE;
  1649. Xextern char **environ;
  1650. X
  1651. Xvoid
  1652. Xsetenv(nam,val)
  1653. Xchar *nam, *val;
  1654. X{
  1655. X    register int i=envix(nam);        /* where does it go? */
  1656. X
  1657. X    if (!environ[i]) {            /* does not exist yet */
  1658. X    if (firstsetenv) {        /* need we copy environment? */
  1659. X        int j;
  1660. X#ifndef lint
  1661. X        char **tmpenv = (char**)    /* point our wand at memory */
  1662. X        safemalloc((i+2) * sizeof(char*));
  1663. X#else
  1664. X        char **tmpenv = Null(char **);
  1665. X#endif /* lint */
  1666. X    
  1667. X        firstsetenv = FALSE;
  1668. X        for (j=0; j<i; j++)        /* copy environment */
  1669. X        tmpenv[j] = environ[j];
  1670. X        environ = tmpenv;        /* tell exec where it is now */
  1671. X    }
  1672. X#ifndef lint
  1673. X    else
  1674. X        environ = (char**) saferealloc((char*) environ,
  1675. X        (i+2) * sizeof(char*));
  1676. X                    /* just expand it a bit */
  1677. X#endif /* lint */
  1678. X    environ[i+1] = Nullch;    /* make sure it's null terminated */
  1679. X    }
  1680. X    environ[i] = safemalloc(strlen(nam) + strlen(val) + 2);
  1681. X                    /* this may or may not be in */
  1682. X                    /* the old environ structure */
  1683. X    sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
  1684. X}
  1685. X
  1686. Xint
  1687. Xenvix(nam)
  1688. Xchar *nam;
  1689. X{
  1690. X    register int i, len = strlen(nam);
  1691. X
  1692. X    for (i = 0; environ[i]; i++) {
  1693. X    if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
  1694. X        break;            /* strnEQ must come first to avoid */
  1695. X    }                    /* potential SEGV's */
  1696. X    return i;
  1697. X}
  1698. !STUFFY!FUNK!
  1699. echo Extracting os2/director.c
  1700. sed >os2/director.c <<'!STUFFY!FUNK!' -e 's/X//'
  1701. X/*
  1702. X * @(#)dir.c 1.4 87/11/06 Public Domain.
  1703. X *
  1704. X *  A public domain implementation of BSD directory routines for
  1705. X *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  1706. X *  August 1897
  1707. X *  Ported to OS/2 by Kai Uwe Rommel
  1708. X *  December 1989, February 1990
  1709. X *  Change for HPFS support, October 1990
  1710. X */
  1711. X
  1712. X#include <sys/types.h>
  1713. X#include <sys/stat.h>
  1714. X#include <sys/dir.h>
  1715. X
  1716. X#include <stdlib.h>
  1717. X#include <stdio.h>
  1718. X#include <malloc.h>
  1719. X#include <string.h>
  1720. X#include <ctype.h>
  1721. X
  1722. X#define INCL_NOPM
  1723. X#include <os2.h>
  1724. X
  1725. X
  1726. X#ifndef PERLGLOB
  1727. Xint attributes = A_DIR | A_HIDDEN;
  1728. X
  1729. X
  1730. Xstatic char *getdirent(char *);
  1731. Xstatic void free_dircontents(struct _dircontents *);
  1732. X
  1733. Xstatic HDIR hdir;
  1734. Xstatic USHORT count;
  1735. Xstatic FILEFINDBUF find;
  1736. Xstatic BOOL lower;
  1737. X
  1738. X
  1739. XDIR *opendir(char *name)
  1740. X{
  1741. X  struct stat statb;
  1742. X  DIR *dirp;
  1743. X  char c;
  1744. X  char *s;
  1745. X  struct _dircontents *dp;
  1746. X  char nbuf[MAXPATHLEN + 1];
  1747. X
  1748. X  strcpy(nbuf, name);
  1749. X
  1750. X  if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  1751. X       (strlen(nbuf) > 1) )
  1752. X  {
  1753. X    nbuf[strlen(nbuf) - 1] = 0;
  1754. X
  1755. X    if ( nbuf[strlen(nbuf) - 1] == ':' )
  1756. X      strcat(nbuf, "\\.");
  1757. X  }
  1758. X  else
  1759. X    if ( nbuf[strlen(nbuf) - 1] == ':' )
  1760. X      strcat(nbuf, ".");
  1761. X
  1762. X  if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  1763. X    return NULL;
  1764. X
  1765. X  if ( (dirp = malloc(sizeof(DIR))) == NULL )
  1766. X    return NULL;
  1767. X
  1768. X  if ( nbuf[strlen(nbuf) - 1] == '.' )
  1769. X    strcpy(nbuf + strlen(nbuf) - 1, "*.*");
  1770. X  else
  1771. X    if ( ((c = nbuf[strlen(nbuf) - 1]) == '\\' || c == '/') &&
  1772. X         (strlen(nbuf) == 1) )
  1773. X      strcat(nbuf, "*.*");
  1774. X    else
  1775. X      strcat(nbuf, "\\*.*");
  1776. X
  1777. X  dirp -> dd_loc = 0;
  1778. X  dirp -> dd_contents = dirp -> dd_cp = NULL;
  1779. X
  1780. X  if ((s = getdirent(nbuf)) == NULL)
  1781. X    return dirp;
  1782. X
  1783. X  do
  1784. X  {
  1785. X    if (((dp = malloc(sizeof(struct _dircontents))) == NULL) ||
  1786. X        ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL)      )
  1787. X    {
  1788. X      if (dp)
  1789. X        free(dp);
  1790. X      free_dircontents(dirp -> dd_contents);
  1791. X
  1792. X      return NULL;
  1793. X    }
  1794. X
  1795. X    if (dirp -> dd_contents)
  1796. X      dirp -> dd_cp = dirp -> dd_cp -> _d_next = dp;
  1797. X    else
  1798. X      dirp -> dd_contents = dirp -> dd_cp = dp;
  1799. X
  1800. X    strcpy(dp -> _d_entry, s);
  1801. X    dp -> _d_next = NULL;
  1802. X
  1803. X    dp -> _d_size = find.cbFile;
  1804. X    dp -> _d_mode = find.attrFile;
  1805. X    dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite);
  1806. X    dp -> _d_date = *(unsigned *) &(find.fdateLastWrite);
  1807. X  }
  1808. X  while ((s = getdirent(NULL)) != NULL);
  1809. X
  1810. X  dirp -> dd_cp = dirp -> dd_contents;
  1811. X
  1812. X  return dirp;
  1813. X}
  1814. X
  1815. X
  1816. Xvoid closedir(DIR * dirp)
  1817. X{
  1818. X  free_dircontents(dirp -> dd_contents);
  1819. X  free(dirp);
  1820. X}
  1821. X
  1822. X
  1823. Xstruct direct *readdir(DIR * dirp)
  1824. X{
  1825. X  static struct direct dp;
  1826. X
  1827. X  if (dirp -> dd_cp == NULL)
  1828. X    return NULL;
  1829. X
  1830. X  dp.d_namlen = dp.d_reclen =
  1831. X    strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry));
  1832. X
  1833. X  dp.d_ino = 0;
  1834. X
  1835. X  dp.d_size = dirp -> dd_cp -> _d_size;
  1836. X  dp.d_mode = dirp -> dd_cp -> _d_mode;
  1837. X  dp.d_time = dirp -> dd_cp -> _d_time;
  1838. X  dp.d_date = dirp -> dd_cp -> _d_date;
  1839. X
  1840. X  dirp -> dd_cp = dirp -> dd_cp -> _d_next;
  1841. X  dirp -> dd_loc++;
  1842. X
  1843. X  return &dp;
  1844. X}
  1845. X
  1846. X
  1847. Xvoid seekdir(DIR * dirp, long off)
  1848. X{
  1849. X  long i = off;
  1850. X  struct _dircontents *dp;
  1851. X
  1852. X  if (off >= 0)
  1853. X  {
  1854. X    for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next);
  1855. X
  1856. X    dirp -> dd_loc = off - (i + 1);
  1857. X    dirp -> dd_cp = dp;
  1858. X  }
  1859. X}
  1860. X
  1861. X
  1862. Xlong telldir(DIR * dirp)
  1863. X{
  1864. X  return dirp -> dd_loc;
  1865. X}
  1866. X
  1867. X
  1868. Xstatic void free_dircontents(struct _dircontents * dp)
  1869. X{
  1870. X  struct _dircontents *odp;
  1871. X
  1872. X  while (dp)
  1873. X  {
  1874. X    if (dp -> _d_entry)
  1875. X      free(dp -> _d_entry);
  1876. X
  1877. X    dp = (odp = dp) -> _d_next;
  1878. X    free(odp);
  1879. X  }
  1880. X}
  1881. X
  1882. X
  1883. Xstatic
  1884. X#endif
  1885. Xint IsFileSystemFAT(char *dir)
  1886. X{
  1887. X  USHORT nDrive;
  1888. X  ULONG lMap;
  1889. X  BYTE bData[64], bName[3];
  1890. X  USHORT cbData;
  1891. X
  1892. X  if ( _osmode == DOS_MODE )
  1893. X    return TRUE;
  1894. X  else
  1895. X  {
  1896. X    /* We separate FAT and HPFS file systems here.
  1897. X     * Filenames read from a FAT system are converted to lower case
  1898. X     * while the case of filenames read from a HPFS (and other future
  1899. X     * file systems, like Unix-compatibles) is preserved.
  1900. X     */
  1901. X
  1902. X    if ( isalpha(dir[0]) && (dir[1] == ':') )
  1903. X      nDrive = toupper(dir[0]) - '@';
  1904. X    else
  1905. X      DosQCurDisk(&nDrive, &lMap);
  1906. X
  1907. X    bName[0] = (char) (nDrive + '@');
  1908. X    bName[1] = ':';
  1909. X    bName[2] = 0;
  1910. X
  1911. X    cbData = sizeof(bData);
  1912. X
  1913. X    if ( !DosQFSAttach(bName, 0U, 1U, bData, &cbData, 0L) )
  1914. X      return !strcmp(bData + (*(USHORT *) (bData + 2) + 7), "FAT");
  1915. X    else
  1916. X      return FALSE;
  1917. X
  1918. X    /* End of this ugly code */
  1919. X  }
  1920. X}
  1921. X
  1922. X#ifndef PERLGLOB
  1923. Xstatic char *getdirent(char *dir)
  1924. X{
  1925. X  int done;
  1926. X
  1927. X  if (dir != NULL)
  1928. X  {                       /* get first entry */
  1929. X    lower = IsFileSystemFAT(dir);
  1930. X
  1931. X    hdir = HDIR_CREATE;
  1932. X    count = 1;
  1933. X    done = DosFindFirst(dir, &hdir, attributes,
  1934. X            &find, sizeof(find), &count, 0L);
  1935. X  }
  1936. X  else                       /* get next entry */
  1937. X    done = DosFindNext(hdir, &find, sizeof(find), &count);
  1938. X
  1939. X  if ( lower )
  1940. X    strlwr(find.achName);
  1941. X
  1942. X  if (done == 0)
  1943. X    return find.achName;
  1944. X  else
  1945. X  {
  1946. X    DosFindClose(hdir);
  1947. X    return NULL;
  1948. X  }
  1949. X}
  1950. X#endif
  1951. !STUFFY!FUNK!
  1952. echo Extracting makedepend.SH
  1953. sed >makedepend.SH <<'!STUFFY!FUNK!' -e 's/X//'
  1954. Xcase $CONFIG in
  1955. X'')
  1956. X    if test ! -f config.sh; then
  1957. X    ln ../config.sh . || \
  1958. X    ln ../../config.sh . || \
  1959. X    ln ../../../config.sh . || \
  1960. X    (echo "Can't find config.sh."; exit 1)
  1961. X    fi 2>/dev/null
  1962. X    . ./config.sh
  1963. X    ;;
  1964. Xesac
  1965. Xcase "$0" in
  1966. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  1967. Xesac
  1968. Xecho "Extracting makedepend (with variable substitutions)"
  1969. X$spitshell >makedepend <<!GROK!THIS!
  1970. X$startsh
  1971. X# $Header: makedepend.SH,v 4.0 91/03/20 01:27:04 lwall Locked $
  1972. X#
  1973. X# $Log:    makedepend.SH,v $
  1974. X# Revision 4.0  91/03/20  01:27:04  lwall
  1975. X# 4.0 baseline.
  1976. X# 
  1977. X# 
  1978. X
  1979. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
  1980. X
  1981. Xcat='$cat'
  1982. Xcppflags='$cppflags'
  1983. Xcp='$cp'
  1984. Xcpp='$cppstdin'
  1985. Xecho='$echo'
  1986. Xegrep='$egrep'
  1987. Xexpr='$expr'
  1988. Xmv='$mv'
  1989. Xrm='$rm'
  1990. Xsed='$sed'
  1991. Xsort='$sort'
  1992. Xtest='$test'
  1993. Xtr='$tr'
  1994. Xuniq='$uniq'
  1995. X!GROK!THIS!
  1996. X
  1997. X$spitshell >>makedepend <<'!NO!SUBS!'
  1998. X
  1999. X$cat /dev/null >.deptmp
  2000. X$rm -f *.c.c c/*.c.c
  2001. Xif test -f Makefile; then
  2002. X    mf=Makefile
  2003. Xelse
  2004. X    mf=makefile
  2005. Xfi
  2006. Xif test -f $mf; then
  2007. X    defrule=`<$mf sed -n        \
  2008. X    -e '/^\.c\.o:.*;/{'        \
  2009. X    -e    's/\$\*\.c//'        \
  2010. X    -e    's/^[^;]*;[     ]*//p'    \
  2011. X    -e    q                \
  2012. X    -e '}'                \
  2013. X    -e '/^\.c\.o: *$/{'        \
  2014. X    -e    N                \
  2015. X    -e    's/\$\*\.c//'        \
  2016. X    -e    's/^.*\n[     ]*//p'        \
  2017. X    -e    q                \
  2018. X    -e '}'`
  2019. Xfi
  2020. Xcase "$defrule" in
  2021. X'') defrule='$(CC) -c $(CFLAGS)' ;;
  2022. Xesac
  2023. X
  2024. Xmake clist || ($echo "Searching for .c files..."; \
  2025. X    $echo *.c | $tr ' ' '\012' | $egrep -v '\*' >.clist)
  2026. Xfor file in `$cat .clist`; do
  2027. X# for file in `cat /dev/null`; do
  2028. X    case "$file" in
  2029. X    *.c) filebase=`basename $file .c` ;;
  2030. X    *.y) filebase=`basename $file .c` ;;
  2031. X    esac
  2032. X    $echo "Finding dependencies for $filebase.o."
  2033. X    $sed -n <$file >$file.c \
  2034. X    -e "/^${filebase}_init(/q" \
  2035. X    -e '/^#/{' \
  2036. X    -e 's|/\*.*$||' \
  2037. X    -e 's|\\$||' \
  2038. X    -e p \
  2039. X    -e '}'
  2040. X    $cpp -I/usr/local/include -I. $cppflags $file.c | \
  2041. X    $sed \
  2042. X    -e '/^# *[0-9]/!d' \
  2043. X    -e 's/^.*"\(.*\)".*$/'$filebase'.o: \1/' \
  2044. X    -e 's|: \./|: |' \
  2045. X    -e 's|\.c\.c|.c|' | \
  2046. X    $uniq | $sort | $uniq >> .deptmp
  2047. Xdone
  2048. X
  2049. X$sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
  2050. X
  2051. Xmake shlist || ($echo "Searching for .SH files..."; \
  2052. X    $echo *.SH | $tr ' ' '\012' | $egrep -v '\*' >.shlist)
  2053. Xif $test -s .deptmp; then
  2054. X    for file in `cat .shlist`; do
  2055. X    $echo `$expr X$file : 'X\(.*\).SH`: $file config.sh \; \
  2056. X        /bin/sh $file >> .deptmp
  2057. X    done
  2058. X    $echo "Updating Makefile..."
  2059. X    $echo "# If this runs make out of memory, delete /usr/include lines." \
  2060. X    >> Makefile.new
  2061. X    $sed 's|^\(.*\.o:\) *\(.*/.*\.c\) *$|\1 \2; '"$defrule \2|" .deptmp \
  2062. X       >>Makefile.new
  2063. Xelse
  2064. X    make hlist || ($echo "Searching for .h files..."; \
  2065. X    $echo *.h | $tr ' ' '\012' | $egrep -v '\*' >.hlist)
  2066. X    $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
  2067. X    $egrep '^#include ' `cat .clist` `cat .hlist`  >.deptmp
  2068. X    $echo "Updating Makefile..."
  2069. X    <.clist $sed -n                            \
  2070. X    -e '/\//{'                            \
  2071. X    -e   's|^\(.*\)/\(.*\)\.c|\2.o: \1/\2.c; '"$defrule \1/\2.c|p"    \
  2072. X    -e   d                                \
  2073. X    -e '}'                                \
  2074. X    -e 's|^\(.*\)\.c|\1.o: \1.c|p' >> Makefile.new
  2075. X    <.hlist $sed -n 's|\(.*/\)\(.*\)|s= \2= \1\2=|p' >.hsed
  2076. X    <.deptmp $sed -n 's|c:#include "\(.*\)".*$|o: \1|p' | \
  2077. X       $sed 's|^[^;]*/||' | \
  2078. X       $sed -f .hsed >> Makefile.new
  2079. X    <.deptmp $sed -n 's|c:#include <\(.*\)>.*$|o: /usr/include/\1|p' \
  2080. X       >> Makefile.new
  2081. X    <.deptmp $sed -n 's|h:#include "\(.*\)".*$|h: \1|p' | \
  2082. X       $sed -f .hsed >> Makefile.new
  2083. X    <.deptmp $sed -n 's|h:#include <\(.*\)>.*$|h: /usr/include/\1|p' \
  2084. X       >> Makefile.new
  2085. X    for file in `$cat .shlist`; do
  2086. X    $echo `$expr X$file : 'X\(.*\).SH`: $file config.sh \; \
  2087. X        /bin/sh $file >> Makefile.new
  2088. X    done
  2089. Xfi
  2090. X$rm -f Makefile.old
  2091. X$cp Makefile Makefile.old
  2092. X$cp Makefile.new Makefile
  2093. X$rm Makefile.new
  2094. X$echo "# WARNING: Put nothing here or make depend will gobble it up!" >> Makefile
  2095. X$rm -f .deptmp `sed 's/\.c/.c.c/' .clist` .shlist .clist .hlist .hsed
  2096. X
  2097. X!NO!SUBS!
  2098. X$eunicefix makedepend
  2099. Xchmod +x makedepend
  2100. Xcase `pwd` in
  2101. X*SH)
  2102. X    $rm -f ../makedepend
  2103. X    ln makedepend ../makedepend
  2104. X    ;;
  2105. Xesac
  2106. !STUFFY!FUNK!
  2107. echo " "
  2108. echo "End of kit 30 (of 36)"
  2109. cat /dev/null >kit30isdone
  2110. run=''
  2111. config=''
  2112. 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
  2113.     if test -f kit${iskit}isdone; then
  2114.     run="$run $iskit"
  2115.     else
  2116.     todo="$todo $iskit"
  2117.     fi
  2118. done
  2119. case $todo in
  2120.     '')
  2121.     echo "You have run all your kits.  Please read README and then type Configure."
  2122.     for combo in *:AA; do
  2123.         if test -f "$combo"; then
  2124.         realfile=`basename $combo :AA`
  2125.         cat $realfile:[A-Z][A-Z] >$realfile
  2126.         rm -rf $realfile:[A-Z][A-Z]
  2127.         fi
  2128.     done
  2129.     rm -rf kit*isdone
  2130.     chmod 755 Configure
  2131.     ;;
  2132.     *)  echo "You have run$run."
  2133.     echo "You still need to run$todo."
  2134.     ;;
  2135. esac
  2136. : Someone might mail this, so...
  2137. exit
  2138.  
  2139. exit 0 # Just in case...
  2140. -- 
  2141. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2142. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2143. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2144. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2145.