home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume39 / dist-3.0 / part07 < prev    next >
Encoding:
Text File  |  1993-08-18  |  55.3 KB  |  1,972 lines

  1. Newsgroups: comp.sources.misc
  2. From: Raphael Manfredi <ram@acri.fr>
  3. Subject: v39i011:  dist-3.0 - Configure script generator and related tools, Part07/28
  4. Message-ID: <1993Aug18.184126.17427@sparky.sterling.com>
  5. X-Md4-Signature: 97765ee6de84ced4d0140d1f37ab6bb4
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Advanced Computer Research Institute, Lyon, France.
  8. Date: Wed, 18 Aug 1993 18:41:26 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: Raphael Manfredi <ram@acri.fr>
  12. Posting-number: Volume 39, Issue 11
  13. Archive-name: dist-3.0/part07
  14. Environment: UNIX, Perl, RCS
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  21. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  22. # Contents:  kit/makedist.SH mcon/man/mlint.SH pat/patcil.SH
  23. #   pat/patmake.SH pat/patsend.SH
  24. # Wrapped by ram@soft208 on Wed Aug 18 14:42:19 1993
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. echo If this archive is complete, you will see the following message:
  27. echo '          "shar: End of archive 7 (of 28)."'
  28. if test -f 'kit/makedist.SH' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'kit/makedist.SH'\"
  30. else
  31.   echo shar: Extracting \"'kit/makedist.SH'\" \(11786 characters\)
  32.   sed "s/^X//" >'kit/makedist.SH' <<'END_OF_FILE'
  33. Xcase $CONFIG in
  34. X'')
  35. X    if test -f config.sh; then TOP=.;
  36. X    elif test -f ../config.sh; then TOP=..;
  37. X    elif test -f ../../config.sh; then TOP=../..;
  38. X    elif test -f ../../../config.sh; then TOP=../../..;
  39. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  40. X    else
  41. X        (echo "Can't find config.sh."; exit 1)
  42. X    fi
  43. X    . $TOP/config.sh
  44. X    ;;
  45. Xesac
  46. Xecho "Extracting kit/makedist (with variable substitutions)"
  47. Xcat >makedist <<!GROK!THIS!
  48. X$startperl
  49. X    eval "exec perl -S \$0 \$*"
  50. X        if \$running_under_some_shell;
  51. X
  52. X# $Id: makedist.SH,v 3.0 1993/08/18 12:04:28 ram Exp $
  53. X#
  54. X#  Copyright (c) 1991-1993, Raphael Manfredi
  55. X#  
  56. X#  You may redistribute only under the terms of the Artistic Licence,
  57. X#  as specified in the README file that comes with the distribution.
  58. X#  You may reuse parts of this distribution only within the terms of
  59. X#  that same Artistic Licence; a copy of which may be found at the root
  60. X#  of the source tree for dist 3.0.
  61. X#
  62. X# $Log: makedist.SH,v $
  63. X# Revision 3.0  1993/08/18  12:04:28  ram
  64. X# Baseline for dist 3.0 netwide release.
  65. X#
  66. X
  67. X\$version = '$VERSION';
  68. X\$patchlevel = '$PATCHLEVEL';
  69. X!GROK!THIS!
  70. X$spitshell >>makedist <<'!NO!SUBS!'
  71. X
  72. Xrequire 'getopts.pl';
  73. X&usage unless &Getopts('c:f:dhvqs:V');
  74. X
  75. Xif ($opt_V) {
  76. X    print STDERR "makedist $version PL$patchlevel\n";
  77. X    exit 0;
  78. X} elsif ($opt_h) {
  79. X    &usage;
  80. X}
  81. X
  82. X$MAXKITSIZE = 50000 unless $MAXKITSIZE = $opt_s;
  83. X$KITOVERHEAD = 1800;
  84. X$FILEOVERHEAD = 90;
  85. X$CHOPSIZE = $MAXKITSIZE - $KITOVERHEAD - $FILEOVERHEAD;
  86. X
  87. X$NEWMANI = 'MANIFEST.new' unless $NEWMANI = $opt_f;
  88. X$MANI = 'MANIFEST' unless $opt_f;
  89. X$PACKLIST = 'PACKLIST';
  90. X$PACKNOTES = 'PACKNOTES';
  91. X
  92. X$tmpdir = "/tmp/MKst$$";    # Where to copy distribution
  93. X$tmpdir = '.' if $opt_q;    # Quick mode: no need to copy distribution
  94. X
  95. X&set_sig('aborted');        # Make sure we clean up in case of emergency
  96. X
  97. X&readpackage;
  98. X&get_patchlevel;
  99. X&manifake;
  100. X
  101. Xif ($opt_c) {                # Copy distribution only, no shell archive
  102. X    &distcopy;
  103. X    exit 0;
  104. X}
  105. X
  106. X&distfake;
  107. X©right'init($copyright) if -f $copyright;
  108. X
  109. Xunlink <$package.kit? $package.kit??>;
  110. Xchop($curdir = `pwd`);
  111. Xchdir $tmpdir || die "Can't chdir to $tmpdir.\n";
  112. X
  113. X&maniread;
  114. X&kitlists;
  115. X&manimake;
  116. X&kitbuild;
  117. X&cleanup;
  118. Xexit 0;
  119. X
  120. X# Physically build the kits
  121. Xsub kitbuild {
  122. X    $numkits = $#list;
  123. X    if ($numkits > 9) {
  124. X        $sp = '%02d';
  125. X    } else {
  126. X        $sp = '%d';
  127. X    }
  128. X
  129. X    for ($kitnum = 1; $kitnum <= $numkits; $kitnum++) {
  130. X        $list = $list[$kitnum];
  131. X        $kit = sprintf("$package.kit" . $sp,$kitnum);
  132. X        print "*** Making $kit ***\n";
  133. X        open(KIT,">$curdir/$kit") || do fatal("Can't create $curdir/$kit: $!");
  134. X
  135. X        &kitleader;
  136. X
  137. X        @files = split(' ',$list);
  138. X        reset 'X';
  139. X        for $file (@files) {
  140. X            $_ = $file;
  141. X            while (s|^(.*)/.*$|$1|) {
  142. X                push(@Xdirs,$_) unless $Xseen{$_}++;
  143. X            }
  144. X        }
  145. X        print KIT "mkdir ",join(' ', sort @Xdirs)," 2>/dev/null\n";
  146. X
  147. X        foreach $file (@files) {
  148. X            print "\t",$file,"\n" if $opt_v;
  149. X            print KIT "echo Extracting $file\n";
  150. X            print KIT "sed >$file <<'!STUFFY!FUNK!' -e 's/X//'\n";
  151. X            open(FILE, $file);
  152. X            ©right'reset;            # Reset copyright for new file
  153. X            while (<FILE>) {
  154. X                # Use Lock[e]r as a pattern in case it is applied on ourselves
  155. X                s|Lock[e]r:.*\$|\$|;    # Remove locker mark
  156. X                print KIT ©right'filter($_, 'X');
  157. X            }
  158. X            close FILE;
  159. X            print KIT "!STUFFY!FUNK!\n";
  160. X            -x "$file" && (print KIT "chmod +x $file\n");
  161. X        }
  162. X        &kittrailer;
  163. X        chmod 0755, $kit;
  164. X    }
  165. X}
  166. X
  167. Xsub kitlists {
  168. X    for $filename (keys %comment) {
  169. X        next if $filename =~ m|/$|;        # Skip directories
  170. X        next if -d $filename;            # Better safe than sorry
  171. X        ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  172. X           $blksize,$blocks) = stat($filename);
  173. X
  174. X        # Make sure file is not larger than the CHOPSIZE limit. If it is,
  175. X        # a split is attempted.
  176. X        if ($size > $CHOPSIZE) {
  177. X            print "Splitting $filename...\n" if $opt_v;
  178. X            $file_comment = $comment{$filename};
  179. X            open(FILE, $filename) || die "Can't open $filename: $!\n";
  180. X            $piece = 'AA';
  181. X            ($dir, $name) = ('.', $filename)
  182. X                unless ($dir, $name) = ($filename =~ m|(.*)/(.*)|);
  183. X            $chopped = $dir . '/' . substr($name, 0, 11);
  184. X            $chopped =~ s|^\./||;
  185. X            &fatal("There is already a split file named $chopped")
  186. X                if defined $Chopped{$chopped};
  187. X            $Chopped{$chopped} = $filename;    # Association split <-> real file
  188. X            $size = 0;
  189. X            open(CURPIECE, ">$chopped:$piece") ||
  190. X                &fatal("Can't create $chopped:$piece: $!");
  191. X            while (<FILE>) {
  192. X                if ($size + length($_) > $CHOPSIZE) {
  193. X                    close CURPIECE;
  194. X                    $size{"$chopped:$piece"} = $size;
  195. X                    $comment{"$chopped:$piece"} = "$file_comment (part $piece)";
  196. X                    push(@files, "$chopped:$piece");
  197. X                    print "\t$chopped:$piece ($size bytes)\n" if $opt_v;
  198. X                    $size = 0;
  199. X                    $piece++;        # AA -> AB, etc...
  200. X                    open(CURPIECE, ">$chopped:$piece") ||
  201. X                        &fatal("Can't create $chopped:$piece: $!");
  202. X                }
  203. X                print CURPIECE $_;
  204. X                $size += length($_);
  205. X            }
  206. X            close FILE;
  207. X            close CURPIECE;
  208. X            $size{"$chopped:$piece"} = $size;
  209. X            $comment{"$chopped:$piece"} = "$file_comment (part $piece)";
  210. X            push(@files, "$chopped:$piece");
  211. X            print "\t$chopped:$piece ($size bytes)\n" if $opt_v;
  212. X            delete $comment{$filename};        # File split, not in PACKLIST
  213. X        } else {
  214. X            $size += 1000000 if $filename =~ /README/;
  215. X            $size{$filename} = $size;
  216. X            push(@files, "$filename");
  217. X        }
  218. X    }
  219. X
  220. X    # Build a file PACKNOTES to reconstruct split files
  221. X    if (defined %Chopped) {
  222. X        open(PACKNOTES, ">$PACKNOTES") || &fatal("Can't create PACKNOTES: $!");
  223. X        foreach (keys %Chopped) {
  224. X            print PACKNOTES <<EOC;
  225. Xecho 'Building $Chopped{$_}...'
  226. Xcat $_:[A-Z][A-Z] > $Chopped{$_}
  227. Xrm -f $_:[A-Z][A-Z]
  228. XEOC
  229. X        }
  230. X        close PACKNOTES;
  231. X        push(@files, $PACKNOTES);
  232. X        $comment{$PACKNOTES} = 'Script to reconstruct split files';
  233. X        ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  234. X           $blksize,$blocks) = stat($PACKNOTES);
  235. X        $size{$PACKNOTES} = $size;
  236. X    }
  237. X
  238. X    # Currently, file PACKLIST does not exist, so its size is unknown and
  239. X    # it cannot be correctly put in one archive. Therefore, we take the
  240. X    # size of MANIFEST.new, which will give us a good estimation.
  241. X    push(@files, 'PACKLIST');
  242. X
  243. X    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  244. X       $blksize,$blocks) = stat($NEWMANI);
  245. X    $size{$PACKLIST} = $size;
  246. X
  247. X    sub revnum { $size{$a} < $size{$b} ? 1 : $size{$a} > $size{$b} ? -1 : 0; }
  248. X    @files = sort revnum @files;
  249. X
  250. X    for (@files) {
  251. X        $size = $size{$_};
  252. X        $size -= 1000000 if /README/;
  253. X        $i=1;
  254. X        while (($newtot = int($tot[$i] + $size + $size/40 + $FILEOVERHEAD)) >
  255. X            $MAXKITSIZE-$KITOVERHEAD && $tot[$i]) {
  256. X                $i++;
  257. X        }
  258. X        $tot[$i] = $newtot;
  259. X        print "Adding $_ to kit $i giving $newtot bytes\n" if $opt_d;
  260. X        $kit{$_} = $i;
  261. X        $list[$i] .= " $_";
  262. X    }
  263. X}
  264. X
  265. X# Read manifest file and initialize the %comment array.
  266. Xsub maniread {
  267. X    do fatal("You don't have a $NEWMANI file.  Run manifake")
  268. X        unless -f "$NEWMANI";
  269. X    open(NEWMANI,$NEWMANI) || do fatal("Can't read $NEWMANI: $!");
  270. X    while (<NEWMANI>) {
  271. X        ($key,$val) = split(' ',$_,1) unless ($key,$val) = /^(\S+)\s+(.*)/;
  272. X        $comment{$key} = $val;
  273. X    }
  274. X    close NEWMANI;
  275. X}
  276. X
  277. X# MANIFEST and MANIFEST.new must say the same thing.  Create the
  278. X# PACKLIST file (thus avoiding kit numbers in MANIFEST, which causes big
  279. X# patches when only re-ordering occurred).  Note that PACKLIST should
  280. X# not appear in MANIFEST.new (the user may remove it).
  281. Xsub manimake {
  282. X    # Add built packlist
  283. X    $comment{$PACKLIST} = 'Which files came with which kits';
  284. X
  285. X    open(PACKLIST, ">$PACKLIST") || do fatal("Can't create $PACKLIST: $!");
  286. X    print PACKLIST
  287. X"After all the $package kits are run you should have the following files:
  288. X
  289. XFilename                   Kit Description
  290. X--------                   --- -----------
  291. X";
  292. X    for (sort keys(comment)) {
  293. X        printf PACKLIST "%-27s %2s %.47s\n", $_, $kit{$_}, $comment{$_};
  294. X    }
  295. X    close PACKLIST;
  296. X}
  297. X
  298. Xsub kitleader {
  299. X    local($plevel);
  300. X    $plevel = " at patchlevel $patch_level" if $patch_level ne '';
  301. X    print KIT <<EOH;
  302. X#! /bin/sh
  303. X#
  304. X# This is $package version $baserev$plevel.
  305. X# Make a new directory for the $package sources, cd to it, and run kits 1 up
  306. X# to $numkits through sh.  When all $numkits kits have been run, read README.
  307. X#
  308. Xecho " "
  309. Xcat <<EOM
  310. XThis is $package $baserev$plevel, kit $kitnum (of $numkits):
  311. XIf this shell archive is complete, the line "End of kit $kitnum (of $numkits)"
  312. Xwill echo at the end.
  313. XEOM
  314. Xexport PATH || (echo "Please use sh to unpack this archive." ; kill \$\$)
  315. XEOH
  316. X}
  317. X
  318. Xsub kittrailer {
  319. X    $rangelist = '';
  320. X    for ($i = 1; $i <= $numkits; $i++) {
  321. X        $rangelist .= ' ' . $i;
  322. X    }
  323. X    print KIT <<EOM;
  324. Xecho \"End of kit $kitnum (of $numkits)\"
  325. Xecho \" \"
  326. Xcat /dev/null >kit${kitnum}isdone
  327. Xrun=''
  328. Xconfig=''
  329. Xfor iskit in$rangelist; do
  330. X    if test -f kit\${iskit}isdone; then
  331. X        run=\"\$run \$iskit\"
  332. X    else
  333. X        todo=\"\$todo \$iskit\"
  334. X    fi
  335. Xdone
  336. Xcase \$todo in
  337. X    '')
  338. X        echo \"You have run all your kits.\"
  339. XEOM
  340. X    if (defined %Chopped) {        # Some splitting occurred
  341. X        print KIT <<EOM;
  342. X        if test -f $PACKNOTES; then
  343. X            sh $PACKNOTES
  344. X        else
  345. X            echo \"You have to rebuild split files by hand (see $PACKLIST).\"
  346. X        fi
  347. XEOM
  348. X    }
  349. X    if (-f "README" && -f "Configure") {
  350. X        print KIT
  351. X"        echo \"Please read README and then type Configure.\"
  352. X        chmod 755 Configure\n";
  353. X    } elsif (-f "README") {
  354. X        print KIT
  355. X"        echo \"Please read README first.\"\n";
  356. X    } elsif (-f "Configure") {
  357. X        print KIT
  358. X"        echo \"Please run Configure first.\"
  359. X        chmod 755 Configure\n";
  360. X    }
  361. X    print KIT <<EOM;
  362. X        rm -f kit*isdone
  363. X        ;;
  364. X    *)  echo \"You have run\$run.\"
  365. X        echo \"You still need to run\$todo.\"
  366. X        ;;
  367. Xesac
  368. X: Someone might mail this, so exit before signature...
  369. Xexit 0
  370. XEOM
  371. X}
  372. X
  373. Xsub get_patchlevel {
  374. X    $patch_level = '';
  375. X    if (-f 'patchlevel.h') {
  376. X        open(PL, 'patchlevel.h');
  377. X        while (<PL>) {
  378. X            /^#define\s+PATCHLEVEL\s+(\w+)/ && ($patch_level = $1);
  379. X        }
  380. X        close PL;
  381. X    }
  382. X}
  383. X
  384. Xsub distfake {
  385. X    return if $opt_q;
  386. X    local($sw);
  387. X    $sw = 's' unless $opt_v;
  388. X    mkdir($tmpdir, 0700) || die "Can't create directory $tmpdir.\n";
  389. X    print "Building a copy of distribution in $tmpdir...\n" if $opt_v;
  390. X    system 'perl', '-S', 'patcol', "-a$sw", '-f', $NEWMANI, '-d', $tmpdir;
  391. X    system 'cp', $NEWMANI, "$tmpdir/$NEWMANI"
  392. X        unless -f "$tmpdir/$NEWMANI" && !$opt_f;
  393. X}
  394. X
  395. Xsub distcopy {
  396. X    local($sw);            # Switch to force patcol to copy checked out files
  397. X    &makedir($opt_c);
  398. X    print "Building a copy of distribution in $opt_c...\n" if $opt_v;
  399. X    $sw = 'c' if $opt_q;
  400. X    $sw .= 's' unless $opt_v;
  401. X    system 'perl', '-S', 'patcol', "-aRC$sw", '-f', $NEWMANI, '-d', $opt_c;
  402. X}
  403. X
  404. Xsub distrm {
  405. X    return if $opt_q;
  406. X    print "Removing distribution in $tmpdir...\n" if $opt_v;
  407. X    chdir "/";            # Do not stay in removed directory...
  408. X    system '/bin/rm', '-rf', "$tmpdir";
  409. X}
  410. X
  411. Xsub splitrm {
  412. X    foreach $base (keys %Chopped) {
  413. X        print "Removing split files for $base:\n" if $opt_v;
  414. X        $piece = 'AA';
  415. X        while (-f "$base:$piece") {
  416. X            print "\t$base:$piece\n" if $opt_v;
  417. X            unlink "$base:$piece";
  418. X            $piece++;        # AA -> AB, etc...
  419. X        }
  420. X    }
  421. X}
  422. X
  423. Xsub cleanup {
  424. X    &distrm if -d $tmpdir;
  425. X    if ($opt_q) {
  426. X        &splitrm;        # Remove in-place split files
  427. X        unlink $PACKLIST, $PACKNOTES;
  428. X    }
  429. X}
  430. X
  431. Xsub fatal {
  432. X    local($reason) = shift(@_);
  433. X    &cleanup;
  434. X    die "$reason\n";
  435. X}
  436. X
  437. Xsub set_sig {
  438. X    local($handler) = @_;
  439. X    $SIG{'HUP'} = $handler;
  440. X    $SIG{'INT'} = $handler;
  441. X    $SIG{'QUIT'} = $handler;
  442. X    $SIG{'TERM'} = $handler;
  443. X}
  444. X
  445. Xsub aborted {
  446. X    &set_sig('IGNORE');
  447. X    $opt_v = 1;        # Force verbose message in distrm
  448. X    &cleanup;
  449. X    print "Aborted.\n";
  450. X    exit 1;
  451. X}
  452. X
  453. Xsub usage {
  454. X    print STDERR <<EOM;
  455. XUsage: makedist [-dhqvV] [-c dir] [-s size] [-f manifest]
  456. X  -c : copy files in dir, do not build any shell archive.
  457. X  -d : debug mode.
  458. X  -f : use this file as manifest.
  459. X  -h : print this help message and exits.
  460. X  -q : quick mode: use checked-out files.
  461. X  -s : set maximum pack size.
  462. X  -v : verbose mode.
  463. X  -V : print version number and exits.
  464. XEOM
  465. X    exit 1;
  466. X}
  467. X
  468. X!NO!SUBS!
  469. X$grep -v '^;#' ../pl/package.pl >>makedist
  470. X$grep -v '^;#' ../pl/manifake.pl | \
  471. X    $sed -e 's|die \(.*\);|do fatal(\1);|' >>makedist
  472. X$grep -v '^;#' ../pl/copyright.pl >>makedist
  473. X$grep -v '^;#' ../pl/makedir.pl >>makedist
  474. Xchmod +x makedist
  475. X$eunicefix makedist
  476. END_OF_FILE
  477.   if test 11786 -ne `wc -c <'kit/makedist.SH'`; then
  478.     echo shar: \"'kit/makedist.SH'\" unpacked with wrong size!
  479.   fi
  480.   # end of 'kit/makedist.SH'
  481. fi
  482. if test -f 'mcon/man/mlint.SH' -a "${1}" != "-c" ; then 
  483.   echo shar: Will not clobber existing file \"'mcon/man/mlint.SH'\"
  484. else
  485.   echo shar: Extracting \"'mcon/man/mlint.SH'\" \(11846 characters\)
  486.   sed "s/^X//" >'mcon/man/mlint.SH' <<'END_OF_FILE'
  487. Xcase $CONFIG in
  488. X'')
  489. X    if test -f config.sh; then TOP=.;
  490. X    elif test -f ../config.sh; then TOP=..;
  491. X    elif test -f ../../config.sh; then TOP=../..;
  492. X    elif test -f ../../../config.sh; then TOP=../../..;
  493. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  494. X    else
  495. X        (echo "Can't find config.sh."; exit 1)
  496. X    fi
  497. X    . $TOP/config.sh
  498. X    ;;
  499. Xesac
  500. Xcase "$0" in
  501. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  502. Xesac
  503. Xecho "Extracting mcon/man/metalint.$manext (with variable substitutions)"
  504. X$rm -f metalint.$manext
  505. X$spitshell >metalint.$manext <<!GROK!THIS!
  506. X.TH METACONFIG $manext "Version $VERSION PL$PATCHLEVEL"
  507. X''' @(#) Manual page for metalint
  508. X'''
  509. X''' $Id: mlint.SH,v 3.0 1993/08/18 12:10:15 ram Exp $
  510. X'''
  511. X'''  Copyright (c) 1991-1993, Raphael Manfredi
  512. X'''  
  513. X'''  You may redistribute only under the terms of the Artistic Licence,
  514. X'''  as specified in the README file that comes with the distribution.
  515. X'''  You may reuse parts of this distribution only within the terms of
  516. X'''  that same Artistic Licence; a copy of which may be found at the root
  517. X'''  of the source tree for dist 3.0.
  518. X'''
  519. X''' $Log: mlint.SH,v $
  520. X''' Revision 3.0  1993/08/18  12:10:15  ram
  521. X''' Baseline for dist 3.0 netwide release.
  522. X'''
  523. X'''
  524. X.SH NAME
  525. Xmetalint \- a metaconfig unit consistency checker
  526. X.SH SYNOPSIS
  527. X.B metalint
  528. X[ \-\fBhklsV\fR ]
  529. X.SH DESCRIPTION
  530. X.I Metalint
  531. Xparses the units and performs some extensive consistency checks, to make sure
  532. Xthe whole set is sound. Due to the relatively huge amount of units available,
  533. Xit is becoming very difficult to maintain the units manually, and an automated
  534. Xprocess can be of real help, although not perfect.
  535. X.PP
  536. X.I Metalint
  537. Xoperates from within your top level package directory and is used to make sure
  538. Xyour own private units are correctly relying on the publicly available units.
  539. XIf you intensively develop new units, you should run \fImetalint\fR on them
  540. Xbefore making them publicly available.
  541. X.SH OPTIONS
  542. X.I Metalint
  543. Xrecognizes the following set of options:
  544. X.TP 15
  545. X.B \-h
  546. XPrint a short usage description and exit.
  547. X.TP
  548. X.B \-k
  549. XKeep temporary \fI.MT\fR directory.
  550. X.TP
  551. X.B \-l
  552. X(not implemented yet) By default, \fImetalint\fR only reports problems related
  553. Xto your own private units. This switch directs \fImetalint\fR to also report
  554. Xproblems in publicly available units.
  555. X.TP
  556. X.B \-s
  557. XSilent mode.
  558. X.TP
  559. X.B \-V
  560. XPrint version number and exit.
  561. X.SH DIAGNOSTICS
  562. XThe following diagnostics may be emitted by \fImetalint\fR:
  563. X.TP 5
  564. X"(?MAKE) ignoring duplicate dependency listing line."
  565. XMore than one ?MAKE: line bearing dependencies was found in the unit. There
  566. Xmay be only one such line, although multiple ?MAKE action lines may occur.
  567. X.TP
  568. X"(?MAKE) special unit 'Xxx' should not be listed as made."
  569. XA special unit symbol (first letter capitalized) may only be listed as made
  570. Xin the special unit itself.
  571. X.TP
  572. X"(?MAKE) '+xxx' is listed x times."
  573. XA conditional dependency is listed more than once. This is harmless though.
  574. X.TP
  575. X"(?MAKE) 'xxx' is listed x times."
  576. XA normal depdendency is listed more than once. Again, an harmless error.
  577. X.TP
  578. X"(?MAKE) 'xxx' listed as both conditional and full dependency."
  579. XSymbol is listed as a normal dependency and as a conditional one.
  580. X.I Metaconfig
  581. Xwill consider this as being a full dependency, but that may not be what you
  582. Xinitially wanted...
  583. X.TP
  584. X"(?S) duplicate description for variable '\$xxx'."
  585. XShell symbol is described more than once, and that will produce two entries
  586. Xin the Glossary.
  587. X.TP
  588. X"(?S) variable '\$xxx' is not listed on ?MAKE: line."
  589. XThe unit describes a shell symbol entry which cannot be used externally since
  590. Xnot listed as a dependency.
  591. X.TP
  592. X"(?S) syntax error in ?S: construct."
  593. XSelf explainatory.
  594. X.TP
  595. X"(?C) duplicate description for symbol 'XXX'."
  596. XC symbol is described more than once, and that will produce two entries for
  597. Xit in the Glossary.
  598. X.TP
  599. X"(?C) syntax error in ?C: construct."
  600. XSelf explainatory.
  601. X.TP
  602. X"(?H) symbol 'XXX' was already defined."
  603. XApparently, two ?H: lines are defining the same C symbol.
  604. X.TP
  605. X"(?H) variable '\$xxx' not even listed on ?MAKE: line."
  606. XA variable is used, but not listed on the dependency line.
  607. X.TP
  608. X"(?V) visible declaration in non-special unit ignored."
  609. XVisible declarations (?V: lines) may only appear in special units. Otherwise,
  610. Xthey are meaningless.
  611. X.TP
  612. X"(?V) wanted variable '\$xxx' made visible."
  613. XA wanted variable (described as a dependency on the ?MAKE: line) cannot be
  614. Xmade visible since that does not make any sense: the unit cannot depend on
  615. Xit and then advertise it as being locally defined.
  616. X.TP
  617. X"(?V) defined variable '\$xxx' made visible."
  618. XA defined variable (listed as made on the ?MAKE: line) cannot be made
  619. Xvisible, since it could as well be directly wanted in another unit.
  620. X.TP
  621. X"(?V) variable '\$xxx' already made visible by unit yyy."
  622. XInconsistent declaration: two units are making one single symbol visible...
  623. X.TP
  624. X"(?V) variable '\$xxx' already read-write visible in yyy."
  625. XThe variable was already made visible as read-write by another unit.
  626. X.TP
  627. X"(?V) variable '\$xxx' already read-only visible in yyy."
  628. XThe variable was already made visible as read-only by another unit.
  629. X.TP
  630. X"(?W) variable '\$xxx' already wanted."
  631. XVariable is already wanted, there is no need to explicitely ask for it here.
  632. X.TP
  633. X"(?W) variable '\$xxx' also locally defined."
  634. XA wanted variable would conflict with a locally defined variable and could
  635. Xresult in getting a garbage value.
  636. X.TP
  637. X"(?W) variable '\$xxx' already listed on a ?W: line in 'yyy'."
  638. XThe variable in the shell symbol section of a ?W: line can only appear in
  639. Xone unit.
  640. X.TP
  641. X"(?T) temporary symbol '\$xxx' multiply declared."
  642. XSelf explainatory.
  643. X.TP
  644. X"control sequence '?XXX:' ignored within body."
  645. XAttempt to use a control line other than ?X: or ?LINT: in the unit body,
  646. Xwhich should be only shell code
  647. X.TP
  648. X"variable '\$xxx' is changed."
  649. XA variable listed as wanted in the dependency line is changed. Such a variable
  650. Xshould be read-only for the unit. Use the \fIchange\fR lint hint to suppress
  651. Xthis message in pathological cases.
  652. X.TP
  653. X"no ?MAKE: line describing dependencies."
  654. XEvery unit should have a dependency line, or it will be silently ignored by
  655. X\fImetaconfig\fR.
  656. X.TP
  657. X"symbol '\$xxx' was not described."
  658. XThe shell symbol defined by this unit was not documented. Use the \fIdescribe\fR
  659. Xlint hint to suppress this message.
  660. X.TP
  661. X"C symbol 'XXX' was not described."
  662. XThe C symbol defined by this unit was not documented. Use the \fIknown\fR lint
  663. Xhint to suppress this message.
  664. X.TP
  665. X"C symbol 'XXX' was not defined by any ?H: line."
  666. XA C symbol was advertised by never defined, hence it cannot appear in the
  667. X\fIconfig.h\fR file and is therefore useless...
  668. X.TP
  669. X"variable '\$xxx' should have been set."
  670. XA variable listed on the make line as made by the unit was not set by the
  671. Xshell code body. Use the \fIset\fR lint hint to suppress this message in
  672. Xpathological cases.
  673. X.TP
  674. X"unused dependency variable '\$xxx'."
  675. XApparently no usage is made from a shell variable. Use the \fIchange\fR or
  676. X\fIuse\fR lint hints (depending on the situation) to suppress this message.
  677. X.TP
  678. X"unused conditional variable '\$xxx'.
  679. XApparently no usage is made from this conditional dependency. The \fIchange\fR
  680. Xor \fIuse\fR lint hints can be used to suppress this message.
  681. X.TP
  682. X"unused temporary variable '\$xxx'."
  683. XA variable declared as temporary in a ?T: line is not used. The \fIuse\fR lint
  684. Xhint will fool \fImetalint\fR into thinking it's indeed used.
  685. X.TP
  686. X"unknown control sequence '?XXX:'."
  687. XAttempt to use an unknown control sequence.
  688. X.TP
  689. X"symbol '\$xxx' has no default value."
  690. XA symbol used as a conditional dependency in some unit has no default value
  691. Xset by a ?D: line.
  692. X.TP
  693. X"stale ?MAKE: dependency 'xxx'."
  694. XUnit lists a symbol as a dependency, but that symbol is otherwise unknown, i.e.
  695. Xnever appears as made by any other unit.
  696. X.TP
  697. X"symbol '\$xxx' missing from ?MAKE."
  698. XA symbol used or defined was not listed as a dependency in the ?MAKE: line.
  699. X.TP
  700. X"missing xxx from ?MAKE for visible '\$yyy'."
  701. XA symbol defined as visible by a special unit is used, but that special unit
  702. Xis not part of the dependency line.
  703. X.TP
  704. X"unknown symbol '\$xxx'."
  705. XI have no idea about what this symbol is.
  706. X.TP
  707. X"read-only symbol '\$xxx' is set."
  708. XA symbol that should be read-only is set by the unit's shell code body.
  709. X.TP
  710. X"obsolete symbol 'xxx' is used."
  711. XAn obsolete symbol is used in the unit's shell code.
  712. X.TP
  713. X"undeclared symbol '\$xxx' is set."
  714. XThe unit tries to set a shell variable which has not been otherwise declared
  715. Xas made or as a temporary variable, or whatever.
  716. X.TP
  717. X"C symbol 'xxx' is defined in the following units:"
  718. XThe C symbol is defined in more that one unit. Offending units are listed.
  719. X.TP
  720. X"Shell symbol 'xxx' is defined in the following units:"
  721. XA shell symbol is defined in more than one unit. Offending units folllow.
  722. X.TP
  723. X"Shell symbol 'xxx' is altogether:"
  724. XA shell symbol is defined by some units, obsoleted by others and used as
  725. Xa temporary.
  726. X.TP
  727. X"Shell symbol 'xxx' is both defined and obsoleted:"
  728. XSelf explainatory.
  729. X.TP
  730. X"Shell symbol 'xxx' is both defined and used as temporary:"
  731. XSelf explainatory.
  732. X.TP
  733. X"Shell symbol 'xxx' obsoleted also used as temporary:"
  734. XSelf explainatory.
  735. X.TP
  736. X"definition of '\$XXX' not closed by '?S:.'."
  737. XSelf explainatory.
  738. X.TP
  739. X"definition of 'XXX' not closed by '?C:.'."
  740. XSelf explainatory.
  741. X.TP
  742. X"variable '\$xxx' is defined externally."
  743. XA variable defined externally (i.e. in another unit) is used, without proper
  744. Xdependency information. Use the \fIextern\fR lint hint to suppress this message.
  745. X.TP
  746. X"Cycle found for:"
  747. XThere is a dependency cycle found for the symbols listed. Only the symbols
  748. Xinvolved in the cycle are listed.
  749. X.TP
  750. X"Cycle involves:"
  751. XAn exerpt of the dependencies where the cycle was found is listed. This may
  752. Xinvolve far more symbols than the previous message, because \fImetalint\fR
  753. Xactually rescans the rules to emphasize the cycle and stops whenever it has
  754. Xfound one, i.e. it does not try to minimize it (the cycle is found using
  755. Xanother algorithm, which unfortunately cannot spit it out but only say
  756. Xfor sure there is one).
  757. X.SH REFERENCE
  758. X.I Metalint
  759. Xuses the following control lines, which are otherwise ignored by
  760. X\fImetaconfig\fR:
  761. X.TP 5
  762. X?V:\fIread-only symbols\fR:\fIread-write symbols\fR
  763. XThis line should be used only in special units. It lists all the shell
  764. Xvariable defined by the unit which should not be used directly as dependencies
  765. Xby other units: they must include this special unit in their dependency list
  766. Xif they make use of any of the symbols described here. Those can be viewed
  767. Xas exported symbols which you inherit from when depending from the unit.
  768. XSymbols may be exported read-only or read-write.
  769. X.TP
  770. X?T:\fIshell temporaries\fR
  771. XThis line should list all the shell variables used as temporaries within
  772. Xthe unit's body. This line should be kept accurate, and prevents you from
  773. Xwriting a unit defining a symbol which would be used as a scratch variable
  774. Xin another unit...
  775. X.TP
  776. X?LINT:\fIkeyword\fR \fIsymbol_list\fR
  777. XSpecifies a lint hint. The following keywords are available:
  778. X.RS +10
  779. X.TP 15
  780. X.PD 0
  781. X.I change
  782. Xshell variable ok to be changed
  783. X.TP
  784. X.I define
  785. Xshell variables listed are defined in this unit
  786. X.TP
  787. X.I describe
  788. Xlisted shell variables are described by ?S:
  789. X.TP
  790. X.I extern
  791. Xvariable known to be externally defined
  792. X.TP
  793. X.I known
  794. Xlisted C variables are described
  795. X.TP
  796. X.I set
  797. Xlisted variables are set
  798. X.TP
  799. X.I use
  800. Xvariables listed are used by this unit
  801. X.PD
  802. X.RS -10
  803. X.SH AUTHORS
  804. XHarlan Stenn <harlan@mumps.pfcs.com> wrote the first version, based on
  805. XLarry Wall's \fImetaconfig\fR from dist 2.0.
  806. X.br
  807. XRaphael Manfredi <ram@acri.fr> rewrote it from scratch for 3.0 with a few
  808. Xenhancements.
  809. X.SH FILES
  810. X.TP 10
  811. X.PD 0
  812. XLIB/dist/mcon/U/*.U
  813. XPublic unit files
  814. X.TP
  815. XU/*.U
  816. XPrivate unit files
  817. X.PD
  818. X.sp
  819. X.in +5
  820. Xwhere LIB is $privlibexp.
  821. X.in -5
  822. X.SH BUGS
  823. XIt is almost impossible with the current version to shut up all the
  824. X(spurious) warnings.
  825. X.SH "SEE ALSO"
  826. Xmetaconfig($manext), metaxref($manext)
  827. X!GROK!THIS!
  828. Xchmod 444 metalint.$manext
  829. END_OF_FILE
  830.   if test 11846 -ne `wc -c <'mcon/man/mlint.SH'`; then
  831.     echo shar: \"'mcon/man/mlint.SH'\" unpacked with wrong size!
  832.   fi
  833.   chmod +x 'mcon/man/mlint.SH'
  834.   # end of 'mcon/man/mlint.SH'
  835. fi
  836. if test -f 'pat/patcil.SH' -a "${1}" != "-c" ; then 
  837.   echo shar: Will not clobber existing file \"'pat/patcil.SH'\"
  838. else
  839.   echo shar: Extracting \"'pat/patcil.SH'\" \(12496 characters\)
  840.   sed "s/^X//" >'pat/patcil.SH' <<'END_OF_FILE'
  841. Xcase $CONFIG in
  842. X'')
  843. X    if test -f config.sh; then TOP=.;
  844. X    elif test -f ../config.sh; then TOP=..;
  845. X    elif test -f ../../config.sh; then TOP=../..;
  846. X    elif test -f ../../../config.sh; then TOP=../../..;
  847. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  848. X    else
  849. X        (echo "Can't find config.sh."; exit 1)
  850. X    fi
  851. X    . $TOP/config.sh
  852. X    ;;
  853. Xesac
  854. Xcase "$0" in
  855. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  856. Xesac
  857. Xecho "Extracting pat/patcil (with variable substitutions)"
  858. X$cat >patcil <<!GROK!THIS!
  859. X$startperl
  860. X    eval "exec perl -i~ -S \$0 \$*"
  861. X        if \$running_under_some_shell;
  862. X
  863. X# $Id: patcil.SH,v 3.0 1993/08/18 12:10:40 ram Exp $
  864. X#
  865. X#  Copyright (c) 1991-1993, Raphael Manfredi
  866. X#  
  867. X#  You may redistribute only under the terms of the Artistic Licence,
  868. X#  as specified in the README file that comes with the distribution.
  869. X#  You may reuse parts of this distribution only within the terms of
  870. X#  that same Artistic Licence; a copy of which may be found at the root
  871. X#  of the source tree for dist 3.0.
  872. X#
  873. X# Original Author: Larry Wall <lwall@netlabs.com>
  874. X#
  875. X# $Log: patcil.SH,v $
  876. X# Revision 3.0  1993/08/18  12:10:40  ram
  877. X# Baseline for dist 3.0 netwide release.
  878. X#
  879. X
  880. X\$defeditor = '$defeditor';
  881. X\$pager = '$pager';
  882. X\$version = '$VERSION';
  883. X\$patchlevel = '$PATCHLEVEL';
  884. X!GROK!THIS!
  885. Xcat >>patcil <<'!NO!SUBS!'
  886. X
  887. Xrequire 'getopts.pl';
  888. X&usage unless $#ARGV >= 0;
  889. X&usage unless &Getopts("abfhnpqsV");
  890. X
  891. Xif ($opt_V) {
  892. X    print STDERR "patcil $version PL$patchlevel\n";
  893. X    exit 0;
  894. X} elsif ($opt_h) {
  895. X    &usage;
  896. X}
  897. X
  898. X$RCSEXT = ',v' unless $RCSEXT;
  899. X$PAGER = $ENV{'PAGER'} || "$pager";
  900. X
  901. Xsystem 'mkdir', 'RCS' unless -d 'RCS';
  902. X
  903. Xchop($pwd = `pwd`) unless -f '.package';
  904. Xuntil (-f '.package') {
  905. X    die "No .package file!  Run packinit.\n" unless $pwd;
  906. X    chdir '..' || die "Can't cd ..";
  907. X    $pwd =~ s|(.*)/(.*)|$1|;
  908. X    $prefix = $2 . '/' . $prefix;
  909. X}
  910. Xif ($prefix) {
  911. X    for (@ARGV) {
  912. X        s/^/$prefix/ unless m|^[-/]|;
  913. X    }
  914. X}
  915. X
  916. X# We now are at the top level
  917. X
  918. X&readpackage;
  919. X
  920. Xif (-f 'patchlevel.h') {
  921. X    open(PL,"patchlevel.h") || die "Can't open patchlevel.h\n";
  922. X    while (<PL>) {
  923. X        $bnum = $1 if /^#define\s+PATCHLEVEL\s+(\d+)/;
  924. X    }
  925. X    die "Malformed patchlevel.h file.\n" if $bnum eq '';
  926. X    ++$bnum;
  927. X} else {
  928. X    $bnum=1;
  929. X}
  930. X
  931. Xsystem 'mkdir', 'bugs' unless -d 'bugs';
  932. Xopen(LOGS,">>bugs/.logs$bnum");        # Remember logs for patmake
  933. Xopen(MODS,">>bugs/.mods$bnum");        # Remember modified files
  934. X
  935. Xpush(@sw,'-q') if $opt_q;
  936. Xpush(@sw,'-f') if $opt_f;
  937. X
  938. Xif ($opt_a) {
  939. X    open(MANI,"MANIFEST.new") || die "No MANIFEST.new found.\n";
  940. X    @ARGV = ();
  941. X    while (<MANI>) {
  942. X        chop;
  943. X        s|^\./||;
  944. X        next if m|^patchlevel.h|;        # Special file
  945. X        ($_) = split(' ');
  946. X        next if -d;
  947. X        push(@ARGV,$_);
  948. X    }
  949. X    close MANI;
  950. X} elsif ($opt_n) {
  951. X    &newer;
  952. X}
  953. X
  954. X@filelist = @ARGV;
  955. X
  956. Xsub CLEANUP {
  957. X    print "Warning: restore $ARGV\n";
  958. X    exit 1;
  959. X}
  960. X
  961. Xif ($opt_s) {
  962. X    open(TTY,">/dev/tty");
  963. X    select(TTY);
  964. X    $| = 1;
  965. X    select(stdout);
  966. X    $SIG{'INT'} = 'CLEANUP';
  967. X    while (<>) {
  968. X        if (/^(.*)\$Log[:\$]/) {
  969. X            $comment = $1;
  970. X            $len = length($comment);
  971. X            print;
  972. X            $lastnl = 1;
  973. X            logline: while (<>) {
  974. X                $c = substr($_,0,$len);
  975. X                last logline unless $c eq $comment;
  976. X                $_ = substr($_,$len,999);
  977. X                if ($lastnl) {
  978. X                    unless (/^Revision\s+\d/) {
  979. X                        $_ = $comment . $_;
  980. X                        last logline;
  981. X                    }
  982. X                    $lastnl = 0;
  983. X                } else {
  984. X                    if ($_ eq "\n") {
  985. X                        $lastnl = 1;
  986. X                    }
  987. X                }
  988. X            }
  989. X        }
  990. X    }
  991. X    continue {
  992. X        print;
  993. X        if ($ARGV ne $oldargv) {
  994. X            print TTY "Stripping $ARGV...\n";
  995. X            $oldargv = $ARGV;
  996. X        }
  997. X    }
  998. X    $SIG{'INT'} = 'DEFAULT';
  999. X    close TTY;
  1000. X}
  1001. X
  1002. Xif ($opt_b) {
  1003. X    $flist = &rcsargs(@filelist);
  1004. X    @flist=split(' ',$flist);
  1005. X    system 'rcs', '-u', @flist;
  1006. X    system 'rcs', "-l$revbranch", @flist;
  1007. X    system 'ci', '-l', "-r$revbranch", @sw, @flist;
  1008. X    exit 0;
  1009. X}
  1010. X
  1011. Xopen(MANI,"MANIFEST.new") || die "Can't open MANIFEST.new.\n";
  1012. Xwhile (<MANI>) {
  1013. X    # Find how many spaces the user wants before comments
  1014. X    $space || /(\S+\s+)\S+/ && ($space = length($1));
  1015. X    ($file,$file_comment) = m|(\S+)\s+(.*)|;
  1016. X    $inmani{$file} = 1;                        # File is listed in MANIFEST
  1017. X    $comment{$file} = $file_comment;        # Save comments
  1018. X}
  1019. Xclose MANI;
  1020. X$space = 29 unless $space;        # Default value
  1021. X
  1022. Xfile: foreach $file (@filelist) {
  1023. X    $files = &rcsargs($file);
  1024. X    @files = split(' ',$files);
  1025. X    $file = $files[1] if $file =~ /\.$RCSEXT$/;
  1026. X    unless ($inmani{$file}) {
  1027. X        print "$file does not appear to be in your MANIFEST.new--add? [y] ";
  1028. X        $ans = <stdin>;
  1029. X        if ($ans !~ /^n/i) {
  1030. X            print "MANIFEST.new comment? ";
  1031. X            $file_comment = <stdin>;
  1032. X            chop($file_comment);
  1033. X            $spacenum = $space - length($file);
  1034. X            $blank = " ";
  1035. X            $blank = " " x $spacenum unless $spacenum < 1;
  1036. X            `echo '${file}${blank}$file_comment' >>MANIFEST.new`;
  1037. X            if (-f 'MANIFEST') {
  1038. X                print "(Also adding file to your MANIFEST)\n";
  1039. X                # Add a (new) at the end, so the two manifests will
  1040. X                # differ and thus manifest will get patched correctly.
  1041. X                `echo '${file}${blank}$file_comment (new)' >>MANIFEST`;
  1042. X                print MODS "MANIFEST\n";
  1043. X            }
  1044. X        } else {
  1045. X            $file_comment = "";            # No file, no comment
  1046. X        }
  1047. X    }
  1048. X    $is_first = 0;            # Suppose this is not the first cil
  1049. X    $revs = 0;                # Makes revs a numeric variable
  1050. X    $rlog = `rlog -r$baserev -r$revbranch $files 2>&1`;
  1051. X    ($total) = ($rlog =~ /total revisions: (\d+)/);
  1052. X    ($revs) = ($rlog =~ /selected revisions: (\d+)/);
  1053. X    $comment = &rcscomment($file);
  1054. X    if (!$revs) {
  1055. X        if ($total) {
  1056. X            if ($rlog !~ /locks:\s*;/) {
  1057. X                system 'rcs', '-u', @files;    # unlock branch
  1058. X            }
  1059. X            # New trunck revision
  1060. X            system 'rcs', '-l', @files;        # lock trunk
  1061. X        }
  1062. X        else {
  1063. X            $file_comment = $comment{$file} if $inmani{$file};
  1064. X            if ($comment ne '') {
  1065. X                &feed($file_comment, 'rcs', '-i', "-c$comment", @files);
  1066. X            } else {
  1067. X                &feed($file_comment, 'rcs', '-i', @files);
  1068. X            }
  1069. X        }
  1070. X        if ($opt_p) {        # check in null as trunk revision
  1071. X            rename($file, "$file.xxx");
  1072. X            `cp /dev/null $file` unless -f $file;
  1073. X            &cil_col("empty\n", $baserev);
  1074. X            system 'rcs', "-Nlastpat:$baserev", @files;
  1075. X            rename("$file.xxx", $file);
  1076. X            $mess = &getlog($file);
  1077. X            next file if $mess eq 'nope';
  1078. X            system 'rcs', '-u', @files;        # Unlock trunck
  1079. X            &feed($mess, 'ci', "-l$revbranch", @sw, @files) unless $?;
  1080. X        } else {
  1081. X            $is_first = 1;            # This is the first cil
  1082. X            $mess = &getlog($file);
  1083. X            next file if $mess eq 'nope';
  1084. X            &cil_col($mess, $baserev);
  1085. X            system 'rcs', "-Nlastpat:$baserev", @files;
  1086. X        }
  1087. X    } else {
  1088. X        if (!$opt_f) {
  1089. X            if ($revs == 1) {
  1090. X                $delta = `rcsdiff -r$baserev $files 2>/dev/null`;
  1091. X            } else {
  1092. X                $delta = `rcsdiff -r$revbranch $files 2>/dev/null`;
  1093. X            }
  1094. X            if ($delta eq '') {        # No change in file
  1095. X                print "No changes in $file since last patcil.\n";
  1096. X                next;                # Skip file
  1097. X            }
  1098. X        }
  1099. X        if ($revs == 1) {
  1100. X            $mess = &getlog($file);
  1101. X            next file if $mess eq 'nope';
  1102. X            &cil_cil($mess, $revbranch);
  1103. X        } else {
  1104. X            $mess = &getlog($file);
  1105. X            next file if $mess eq 'nope';
  1106. X            &cil_col($mess, $revbranch);
  1107. X        }
  1108. X    }
  1109. X}
  1110. X
  1111. X# Used for the first revisions on a branch
  1112. Xsub cil_cil {
  1113. X    local($mess) = shift(@_);
  1114. X    local($rev) = shift(@_);
  1115. X    if (&feed($mess, 'ci', @sw, "-l$rev", @files)) {
  1116. X        print "Unlocking and trying again...\n";
  1117. X        system 'rcs', '-u', @files;
  1118. X        &feed($mess, 'ci', @sw, "-l$rev", @files) unless $?;
  1119. X    }
  1120. X}
  1121. X
  1122. X# Run a ci -l on the file. If this fails, try to lock the file first.
  1123. X# If this fails again, try again with a separate checkout.
  1124. Xsub cil_col {
  1125. X    local($mess) = shift(@_);
  1126. X    local($rev) = shift(@_);
  1127. X    if (&feed($mess, 'ci', @sw, "-l$rev", @files)) {
  1128. X        print "Locking and trying again...\n";
  1129. X        if ($rev =~ /\d+\.\d+\.\d+/) {
  1130. X            system 'rcs', "-l$rev", @files;        # Lock branch
  1131. X        } else {
  1132. X            system 'rcs', '-l', @files;            # Lock trunck
  1133. X        }
  1134. X        if (&feed($mess, 'ci', @sw, "-l$rev", @files)) {
  1135. X            print "Trying again with separate checkout...\n";
  1136. X            if (&feed($mess, 'ci', @sw, "-r$rev", @files)) {
  1137. X                system 'rcs', "-u$rev", @files unless $?;
  1138. X                system 'co', "-l$rev", @files unless $?;
  1139. X            } else {
  1140. X                print "Sorry, giving up...\n";
  1141. X            }
  1142. X        }
  1143. X    }
  1144. X}
  1145. X
  1146. Xsub feed {
  1147. X    local($mess) = shift(@_);
  1148. X    open(FORK,"|-") || exec @_;
  1149. X    print FORK $mess;
  1150. X    close FORK;
  1151. X    $?;
  1152. X}
  1153. X
  1154. Xsub getlog {
  1155. X    local($file) = @_;
  1156. X    local($mess) = '';
  1157. X    local($prefix) = "patch$bnum: ";
  1158. X    local($prompt) = $comment;
  1159. X    local($len);
  1160. X    $prompt = '>> ' unless $prompt;
  1161. X    $prefix = '' if $is_first;
  1162. X    print "Type log message for $file (finish with ., CR for previous):\n";
  1163. X    try: for (;;) {
  1164. X        line: for (print "$prompt$prefix";;print "$prompt$prefix") {
  1165. X            if ($always) {
  1166. X                print "\n";
  1167. X                $line = '';
  1168. X            } else {
  1169. X                $line = <stdin>;
  1170. X            }
  1171. X            if ($line =~ /^\.?$/) {
  1172. X                if ($mess) {
  1173. X                    last line;
  1174. X                } else {
  1175. X                    $line = 'p';
  1176. X                }
  1177. X            }
  1178. X            if ($line =~ /^[h?]$/) {
  1179. X                print "
  1180. XCR or .    Terminate log message.
  1181. X!<cmd>    Start command in a subshell.
  1182. XD    Print out diff listing since last patch.
  1183. XN    Give name of the current file.
  1184. XV or E    Call editor with a diff listing.
  1185. Xa    Always use this message.
  1186. Xd    Print out diff listing since last patcil.
  1187. Xf    Forget message I have so far.
  1188. Xh or ?    This help message.
  1189. Xl    List what I have so far.
  1190. Xn    Forget this file; go to next file if any.
  1191. Xp    Append previous message.
  1192. Xr    Print out the rlog for this file.
  1193. Xv or e    Call editor.
  1194. Xx    Toggle patch# prefix.
  1195. X
  1196. X";
  1197. X                next line;
  1198. X            }
  1199. X            if ($line =~ /^!(.*)$/) {
  1200. X                $_ = $1;
  1201. X                $_ = ($ENV{'SHELL'} || "/bin/sh") if $1 eq '';
  1202. X                system $_;
  1203. X                next line;
  1204. X            }
  1205. X            if ($line =~ /^[VE]$/) {
  1206. X                $mess .= "\n" . `rcsdiff -c -rlastpat $files`;
  1207. X            }
  1208. X            if ($line =~ /^[VEve]$/) {
  1209. X                $mess = &edit($mess);
  1210. X                next line;
  1211. X            }
  1212. X            if ($line =~ /^r$/) {
  1213. X                system "rlog $files | $PAGER";
  1214. X                next line;
  1215. X            }
  1216. X            if ($line =~ /^D$/) {
  1217. X                if ($revs == 0) {
  1218. X                    print "Sorry. There is no revision for this file yet.\n";
  1219. X                } else {
  1220. X                    system "rcsdiff -c -rlastpat $files | $PAGER";
  1221. X                }
  1222. X                next line;
  1223. X            }
  1224. X            if ($line =~ /^d$/) {
  1225. X                if ($revs == 0) {
  1226. X                    print "Sorry. There is no revision for this file yet.\n";
  1227. X                }
  1228. X                elsif ($revs == 1) {
  1229. X                    system "rcsdiff -c -r$baserev $files | $PAGER";
  1230. X                } else {
  1231. X                    system "rcsdiff -c -r$revbranch $files | $PAGER";
  1232. X                }
  1233. X                next line;
  1234. X            }
  1235. X            if ($line =~ /^N$/) {
  1236. X                print "Typing log message for $file.\n";
  1237. X                next line;
  1238. X            }
  1239. X            if ($line =~ /^f$/) {
  1240. X                $mess = '';
  1241. X                next line;
  1242. X            }
  1243. X            if ($line =~ /^a$/) {
  1244. X                $always++ if $mess || $prevmess;
  1245. X                next line;
  1246. X            }
  1247. X            if ($line =~ /^n$/) {
  1248. X                $mess = 'nope';
  1249. X                last line;
  1250. X            }
  1251. X            if ($line =~ /^l$/) {
  1252. X                foreach $line (split(/\n/,$mess)) {
  1253. X                    print $prompt,$line,"\n";
  1254. X                }
  1255. X                next line;
  1256. X            }
  1257. X            if ($line =~ /^p$/) {
  1258. X                $mess .= $prevmess;
  1259. X                foreach $line (split(/\n/,$prevmess)) {
  1260. X                    print $prompt,$line,"\n";
  1261. X                }
  1262. X                next line;
  1263. X            }
  1264. X            if ($line =~ /^x$/) {
  1265. X                $prefix = $prefix ? '' : "patch$bnum: ";
  1266. X                next line;
  1267. X            }
  1268. X            $mess .= $prefix . $line;
  1269. X            $len = length($comment . $prefix . $line);
  1270. X            if ($len > 80) {
  1271. X                print "(Warning: last line longer than 80 chars)\n";
  1272. X            } elsif ($len > 72) {        # In case of vi with line numbers
  1273. X                print "(Warning: last line longer than 72 chars)\n";
  1274. X            }
  1275. X            if (length($mess) > 511) {
  1276. X                print "You'll have to trim to less than 512 chars...\n";
  1277. X                sleep(3);
  1278. X                $mess = &edit($mess);
  1279. X            }
  1280. X        }
  1281. X        $mess = $prevmess if $mess eq '';
  1282. X        if (!$mess) {
  1283. X            print "No previous message, try again.\n";
  1284. X            next try;
  1285. X        }
  1286. X        if (length($mess) > 511) {
  1287. X            print "Sorry, that's too long; rcs won't take it.  Try again...\n";
  1288. X            next try;
  1289. X        }
  1290. X        last try;
  1291. X    }
  1292. X    unless ($is_first) {
  1293. X        print LOGS $mess unless $mess eq 'nope';
  1294. X        print MODS "$file\n";
  1295. X    }
  1296. X    $prevmess = $mess unless $mess eq 'nope';
  1297. X    $mess;            # Returned value
  1298. X}
  1299. X
  1300. Xsub geteditor {
  1301. X    local($editor) = $ENV{'VISUAL'};
  1302. X    $editor = $ENV{'EDITOR'} unless $editor;
  1303. X    $editor = $defeditor unless $editor;
  1304. X    $editor = 'vi' unless $editor;
  1305. X    $editor;
  1306. X}
  1307. X
  1308. Xsub edit {
  1309. X    $editor = &geteditor unless $editor;
  1310. X    local($text) = join("\n", @_);
  1311. X    open(TMP,">/tmp/cil$$") || die "Can't create /tmp/cil$$";
  1312. X    print TMP $text;
  1313. X    close TMP;
  1314. X    system $editor, "/tmp/cil$$";
  1315. X    $text = `cat /tmp/cil$$`;
  1316. X    unlink "/tmp/cil$$";
  1317. X    $text;
  1318. X}
  1319. X
  1320. Xsub usage {
  1321. X    print STDERR "Usage: patcil [-abfhnpqsV] [filelist]\n";
  1322. X    print STDERR "  -a : all the files in MANIFEST.new\n";
  1323. X    print STDERR "  -b : batch mode\n";
  1324. X    print STDERR "  -f : force check in (passed through to ci)\n";
  1325. X    print STDERR "  -h : print this message and exit\n";
  1326. X    print STDERR "  -n : all the files newer than patchlevel.h\n";
  1327. X    print STDERR "  -p : patching mode (null trunk revision if new file)\n";
  1328. X    print STDERR "  -q : ask rcs to be quiet\n";
  1329. X    print STDERR "  -s : strip log messages\n";
  1330. X    print STDERR "  -V : print version number and exit\n";
  1331. X    exit 1;
  1332. X}
  1333. X
  1334. X!NO!SUBS!
  1335. X$grep -v '^;#' ../pl/newer.pl >>patcil
  1336. X$grep -v '^;#' ../pl/package.pl >>patcil
  1337. X$grep -v '^;#' ../pl/rcsargs.pl >>patcil
  1338. X$grep -v '^;#' ../pl/comment.pl >>patcil
  1339. Xchmod +x patcil
  1340. X$eunicefix patcil
  1341. END_OF_FILE
  1342.   if test 12496 -ne `wc -c <'pat/patcil.SH'`; then
  1343.     echo shar: \"'pat/patcil.SH'\" unpacked with wrong size!
  1344.   fi
  1345.   # end of 'pat/patcil.SH'
  1346. fi
  1347. if test -f 'pat/patmake.SH' -a "${1}" != "-c" ; then 
  1348.   echo shar: Will not clobber existing file \"'pat/patmake.SH'\"
  1349. else
  1350.   echo shar: Extracting \"'pat/patmake.SH'\" \(11622 characters\)
  1351.   sed "s/^X//" >'pat/patmake.SH' <<'END_OF_FILE'
  1352. Xcase $CONFIG in
  1353. X'')
  1354. X    if test -f config.sh; then TOP=.;
  1355. X    elif test -f ../config.sh; then TOP=..;
  1356. X    elif test -f ../../config.sh; then TOP=../..;
  1357. X    elif test -f ../../../config.sh; then TOP=../../..;
  1358. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  1359. X    else
  1360. X        (echo "Can't find config.sh."; exit 1)
  1361. X    fi
  1362. X    . $TOP/config.sh
  1363. X    ;;
  1364. Xesac
  1365. Xcase "$0" in
  1366. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  1367. Xesac
  1368. Xecho "Extracting pat/patmake (with variable substitutions)"
  1369. Xcat >patmake <<!GROK!THIS!
  1370. X$startperl
  1371. X    eval "exec perl -S \$0 \$*"
  1372. X        if \$running_under_some_shell;
  1373. X
  1374. X# $Id: patmake.SH,v 3.0 1993/08/18 12:10:45 ram Exp $
  1375. X#
  1376. X#  Copyright (c) 1991-1993, Raphael Manfredi
  1377. X#  
  1378. X#  You may redistribute only under the terms of the Artistic Licence,
  1379. X#  as specified in the README file that comes with the distribution.
  1380. X#  You may reuse parts of this distribution only within the terms of
  1381. X#  that same Artistic Licence; a copy of which may be found at the root
  1382. X#  of the source tree for dist 3.0.
  1383. X#
  1384. X# Original Author: Larry Wall <lwall@netlabs.com>
  1385. X# Contribution by: Graham Stoney <greyham@research.canon.oz.au>
  1386. X#
  1387. X# $Log: patmake.SH,v $
  1388. X# Revision 3.0  1993/08/18  12:10:45  ram
  1389. X# Baseline for dist 3.0 netwide release.
  1390. X#
  1391. X#
  1392. X# Revision 2.8.1.3  91/10/11  09:58:51  ram
  1393. X# patch5: allows dot in makefile rules
  1394. X# 
  1395. X# Revision 2.8.1.2  91/07/14  14:00:42  ram
  1396. X# patch1: urgent fix due to a disk crash (file was not synced, grrr...)
  1397. X# 
  1398. X# Revision 2.8.1.1  91/07/14  13:31:01  ram
  1399. X# patch1: added usage message which also briefly describes options
  1400. X# patch1: now uses the perl library getopts.pl for option parsing
  1401. X# 
  1402. X# Revision 2.8  91/07/08  13:26:52  ram
  1403. X# 3.0 alpha baseline.
  1404. X# 
  1405. X
  1406. X\$defeditor='$defeditor';
  1407. X\$version = '$VERSION';
  1408. X\$patchlevel = '$PATCHLEVEL';
  1409. X\$mailer = '$mailer';
  1410. X!GROK!THIS!
  1411. Xcat >>patmake <<'!NO!SUBS!'
  1412. X
  1413. Xrequire 'getopts.pl';
  1414. X&usage unless &Getopts("hV");
  1415. X
  1416. Xif ($opt_V) {
  1417. X    print STDERR "patmake $version PL$patchlevel\n";
  1418. X    exit 0;
  1419. X} elsif ($opt_h) {
  1420. X    &usage;
  1421. X}
  1422. X
  1423. X&readpackage;
  1424. X&readusers;
  1425. X
  1426. X$RCSEXT = ',v' unless $RCSEXT;
  1427. X$FILEOVERHEAD = 40;        # Name of files, Index, Prereq
  1428. X$MAXPATSIZE = 50000;    # Maximum allowed size for a patch
  1429. X$PATOVERHEAD = 2500;    # Litterature
  1430. X$FIRST_PAT = 3000;        # Give space for first patch (descriptions)
  1431. X
  1432. Xif (-f 'patchlevel.h') {
  1433. X    open(PL,"patchlevel.h") || die "Can't open patchlevel.h\n";
  1434. X    while (<PL>) {
  1435. X        if (/^#define\s+PATCHLEVEL\s+(\d+)/) {
  1436. X            $last = $1;
  1437. X            $patchline = $.;    # Record PATCHLEVEL line
  1438. X        }
  1439. X    }
  1440. X    die "Malformed patchlevel.h file.\n" if $last eq '';
  1441. X    $bnum = $last + 1;
  1442. X}
  1443. Xelse {
  1444. X    $patchline = 1;
  1445. X    $bnum = 1;
  1446. X    $last = '';
  1447. X}
  1448. X
  1449. X@ARGV = <[Mm]akefile*>;
  1450. X$mf = '';
  1451. Xif ($#ARGV > 0) {
  1452. X    while (<>) {
  1453. X        $mf .= $_ if /^[a-z.]+\s*:/;    # Rules in makefile
  1454. X    }
  1455. X}
  1456. X$* = 1;
  1457. X$after = '';
  1458. X$after .= "\t\tConfigure -ders\n" if -f 'Configure';
  1459. X$after .= "\t\tmake depend\n" if $mf =~ /^depend:/;
  1460. X$after .= "\t\tmake\n" if $mf;
  1461. X$after .= "\t\tmake test\n" if $mf =~ /^test:/;
  1462. X$after .= "\t\tmake install\n" if $mf =~ /^install:/;
  1463. X$after .= "\t\tmake install.man\n" if $mf =~ /^install\.man:/;
  1464. X$* = 0;
  1465. X
  1466. Xchdir 'bugs' if -d 'bugs';
  1467. X
  1468. Xdie "Patch #$bnum already exists.\n" if -f "patch$bnum";
  1469. X
  1470. X@patlist=<*.$bnum>;
  1471. Xdie "No diff files for patch #$bnum.\n" if $patlist[0] =~ /^\*/;
  1472. X
  1473. X# Look for size of each diff file
  1474. Xfor (@patlist) {
  1475. X    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
  1476. X        $blksize,$blocks) = stat($_);
  1477. X    $size{$_} = $size;
  1478. X}
  1479. X
  1480. X# Sort the array, biggest sizes first
  1481. Xsub revnum { $size{$a} < $size{$b} ? 1 : $size{$a} > $size{$b} ? -1 : 0; }
  1482. X@patlist = sort revnum @patlist;
  1483. X
  1484. X# Put files in a patch
  1485. Xfor (@patlist) {
  1486. X    $i=1;
  1487. X    # Find the patch in which the current file can go
  1488. X    # Divide size by 15 to count the 3 spaces added in front of each line
  1489. X    while (($newtot = int($tot[$i] + $size{$_} + $size{$_}/15 + $FILEOVERHEAD)) >
  1490. X            $MAXPATSIZE-$PATOVERHEAD-($i == 1 ? $FIRST_PAT : 0) && $tot[$i]) {
  1491. X        $i++;
  1492. X    }
  1493. X    # Adding $_ to patch $i giving $newtot bytes
  1494. X    $tot[$i] = $newtot;        # Update size of kit $i
  1495. X    $list[$i] .= " $_";        # Add file to the kit $i
  1496. X}
  1497. X
  1498. X$numpat = $#list;        # Number of patches to generate
  1499. X
  1500. Xif ($numpat > 1) {
  1501. X    print "Warning: generating $numpat patches.\n";
  1502. X    sleep(1);
  1503. X}
  1504. X
  1505. Xif (-s ".logs$bnum") {
  1506. X    $logs = '';
  1507. X    open(LOGS,".logs$bnum");
  1508. X    while (<LOGS>) {
  1509. X        unless ($logseen{$_}) {
  1510. X            $logs .= $_;
  1511. X            $logseen{$_} = 1;
  1512. X            $logsnum++;            # One more log
  1513. X        }
  1514. X    }
  1515. X    close LOGS;
  1516. X    $subs = $logs;
  1517. X    $* = 1;
  1518. X    $logs =~ s/^patch\d+:\s*/\t/g;
  1519. X    $logs =~ s/\n/\n\n/g;
  1520. X    $subs =~ s/^patch\d+:\s*/Subject: /g;
  1521. X    $changes =~ s/^patch\d+:\s*/\t/g;
  1522. X    $* = 0;
  1523. X}
  1524. Xelse {
  1525. X    $subs = "Subject: \n";
  1526. X}
  1527. X
  1528. X$hah = " (hah!)" if $bnum == 1;
  1529. X$patbase = $bnum;            # First patch generated
  1530. X
  1531. X# Try to guess the priority of the patch
  1532. Xif (-s ".mods$bnum") {
  1533. X    open(MODS, ".mods$bnum");
  1534. X    while (<MODS>) {
  1535. X        unless ($fileseen{$_}) {
  1536. X            $fileseen{$_} = 1;
  1537. X            $modsnum++;            # One more modified file
  1538. X        }
  1539. X    }
  1540. X    close MODS;
  1541. X}
  1542. X$modsnum++ unless $modsnum;        # Avoid divisions by zero
  1543. X$mean = $logsnum / $modsnum;
  1544. Xif ($mean > 0.7 && $mean < 1.3) {
  1545. X    $priority = "MEDIUM";
  1546. X} elsif ($mean <= 0.7) {
  1547. X    $priority = "HIGH";        # Small changes
  1548. X} else {
  1549. X    $priority = "LOW";        # Big changes
  1550. X}
  1551. X
  1552. Xfor ($i = 1; $i <= $numpat; $i++) {        # For all patches...
  1553. X    open(PATCH,">patch$bnum") || die "Can't create patch #$bnum";
  1554. X    chop($date=`date`);
  1555. X    print PATCH
  1556. X"System: $package version $baserev
  1557. XPatch #: $bnum
  1558. X";
  1559. X    print PATCH "Priority: $priority\n" unless $priority eq '';
  1560. X    # Print subjects only for first patch
  1561. X    if ($i == 1) {
  1562. X        print PATCH $subs;
  1563. X    } else {
  1564. X        print PATCH "Subject: patch #$patbase, continued\n";
  1565. X    }
  1566. X    print PATCH
  1567. X"Date: $date
  1568. XFrom: $maintname <$maintloc>
  1569. X
  1570. XDescription:
  1571. X";
  1572. X    # Print description and repeat-by only for first patch
  1573. X    if ($i == 1) {
  1574. X        print PATCH 
  1575. X"$logs
  1576. XRepeat-By:
  1577. X";
  1578. X    } else {
  1579. X        print PATCH "\tSee patch #$patbase.\n\n";
  1580. X    }
  1581. X    print PATCH
  1582. X"
  1583. XFix:    From rn, say \"| patch -p -N -d DIR\", where DIR is your $package source
  1584. X    directory.  Outside of rn, say \"cd DIR; patch -p -N <thisarticle\".
  1585. X    If you don't have the patch program, apply the following by hand,
  1586. X    or get patch (version 2.0, latest patchlevel).
  1587. X
  1588. X    After patching:
  1589. X";
  1590. X    # Do $after only after last patch
  1591. X    if ($i == $numpat) {
  1592. X        print PATCH $after;
  1593. X    } else {
  1594. X        printf PATCH
  1595. X"\t\t*** DO NOTHING--INSTALL ALL PATCHES UP THROUGH #%d FIRST ***\n",
  1596. X$patbase + $numpat - 1;
  1597. X    }
  1598. X    print PATCH "
  1599. X    If patch indicates that patchlevel is the wrong version, you may need
  1600. X    to apply one or more previous patches, or the patch may already
  1601. X    have been applied.  See the patchlevel.h file to find out what has or
  1602. X    has not been applied.  In any event, don't continue with the patch.
  1603. X
  1604. X    If you are missing previous patches$hah they can be obtained from me:
  1605. X
  1606. X        $maintname <$maintloc>
  1607. X
  1608. X";
  1609. X    if ($mailagent ne 'false') {
  1610. X        print PATCH
  1611. X"    If you send a mail message of the following form it will greatly speed
  1612. X    processing:
  1613. X
  1614. X        Subject: Command
  1615. X        @SH mailpatch PATH $package $baserev LIST
  1616. X               ^ note the c
  1617. X
  1618. X    where PATH is a return path FROM ME TO YOU either in Internet notation,
  1619. X    or in bang notation from some well-known host, and LIST is the number
  1620. X    of one or more patches you need, separated by spaces, commas, and/or
  1621. X    hyphens.  Saying 35- says everything from 35 to the end.
  1622. X
  1623. X    To get some more detailed instructions, send me the following mail:
  1624. X
  1625. X        Subject: Command
  1626. X        @SH mailhelp PATH
  1627. X
  1628. X";
  1629. X    }
  1630. X    if ($ftpsite) {
  1631. X        print PATCH
  1632. X"    You can also get the patches via anonymous FTP from
  1633. X    $ftpsite.
  1634. X";
  1635. X    }
  1636. X    # Print patchlevel at the top of each patch
  1637. X    print PATCH "
  1638. XIndex: patchlevel.h
  1639. X";
  1640. X    if ($last eq '') {
  1641. X        `echo "#define PATCHLEVEL 1" >patchlevel.h`;
  1642. X        `cp /dev/null patchlevel.h.null`;
  1643. X        print PATCH `diff -c patchlevel.h.null patchlevel.h`;
  1644. X        unlink 'patchlevel.h', 'patchlevel.h.null';
  1645. X    }
  1646. X    else {
  1647. X        print PATCH
  1648. X"Prereq: $last
  1649. X${patchline}c${patchline}
  1650. X< #define PATCHLEVEL $last
  1651. X---
  1652. X> #define PATCHLEVEL $bnum
  1653. X";
  1654. X    }
  1655. X    $last = $bnum;        # Update last patch
  1656. X
  1657. X    @ARGV = split(' ', $list[$i]);
  1658. X    while (<>) { print PATCH; }
  1659. X    print PATCH "\n*** End of Patch $bnum ***\n";
  1660. X    close PATCH;
  1661. X
  1662. X    # Update patchlevel.h file
  1663. X    $editor = $ENV{'VISUAL'};
  1664. X    $editor = $ENV{'EDITOR'} unless $editor;
  1665. X    $editor = $defeditor unless $editor;
  1666. X    $editor = 'vi' unless $editor;
  1667. X    system $editor, "patch$bnum";
  1668. X    if (-s "patch$bnum") {
  1669. X        system 'chmod', '-w', "patch$bnum";        # Protect newly created patch
  1670. X        chdir '..';
  1671. X        `echo "#define PATCHLEVEL 0" >patchlevel.h` unless -f 'patchlevel.h';
  1672. X        open(PL,"patchlevel.h") || die "Can't open patchlevel.h\n";
  1673. X        open(PLN,">patchlevel.h+") || die "Can't create new patchlevel.h\n";
  1674. X        while (<PL>) {
  1675. X            if (/^#define\s+PATCHLEVEL\s+(\d+)/) {
  1676. X                $bnum = $1;
  1677. X                $bnum++;        # Update patch level
  1678. X                print PLN "#define PATCHLEVEL $bnum\n";
  1679. X            } else {
  1680. X                print PLN;        # Simply copy other lines
  1681. X            }
  1682. X        }
  1683. X        close PLN;
  1684. X        close PL;
  1685. X        `mv -f patchlevel.h+ patchlevel.h`;
  1686. X        die "Malformed patchlevel.h file.\n" if $bnum eq '';
  1687. X
  1688. X        if ($newsgroups) {
  1689. X            print "\nDo you wish to post patch #$bnum to $newsgroups? [y] ";
  1690. X            $ans = <stdin>;
  1691. X            system 'patpost', $bnum unless $ans =~ /^n/i;
  1692. X        }
  1693. X        if ($recipients) {
  1694. X            print "\n";
  1695. X            if (0 == ($recipients =~ tr/ //)) {
  1696. X                print "Do you wish to send patch #$bnum to $recipients? [y] ";
  1697. X            } else {
  1698. X                print "The following people are on the recipient list:\n\n";
  1699. X                foreach $addr (split(' ', $recipients)) {
  1700. X                    print "\t$addr\n";
  1701. X                }
  1702. X                print "\nDo you wish to send patch #$bnum to them? [y] ";
  1703. X            }
  1704. X            $ans = <stdin>;
  1705. X            system 'patsend', $bnum, $recipients unless $ans =~ /^n/i;
  1706. X        }
  1707. X        if ($ftpdir) {
  1708. X            print "\nDo you wish to copy patch #$bnum to $ftpdir? [y] ";
  1709. X            $ans = <stdin>;
  1710. X            system 'patftp', $bnum unless $ans =~ /^n/i;
  1711. X        }
  1712. X    utime time, time, 'patchlevel.h';
  1713. X    } else {
  1714. X        unlink "patch$bnum";
  1715. X        die "Aborted.\n";
  1716. X    }
  1717. X
  1718. X    chdir 'bugs' || die "Cannot cd to bugs.\n";
  1719. X    
  1720. X    # Find priority for next patch in loop
  1721. X    $priority='';
  1722. X    open(PATCH, "patch$bnum") || die "Cannot re-open patch #$bnum !\n";
  1723. X    while (<PATCH>) {
  1724. X        /^Priority:\s*(\S+)\s*$/ && ($priority = $1);
  1725. X    }
  1726. X    close PATCH;
  1727. X
  1728. X    $bnum++;    # For next patch in loop
  1729. X}
  1730. X
  1731. X# notify people about it.
  1732. Xif ($notify) {
  1733. X    print "\n";
  1734. X    if (0 == ($notify =~ tr/ //)) {
  1735. X        print "Do you wish to notify $notify? [y] ";
  1736. X    } else {
  1737. X        print "The following people are on the notify list:\n\n";
  1738. X        foreach $addr (split(' ', $notify)) {
  1739. X            print "\t$addr\n";
  1740. X        }
  1741. X        print "\nDo you wish to notify them? [y] ";
  1742. X    }
  1743. X    $ans = <STDIN>;
  1744. X    if ($ans !~ /^n/i) {
  1745. X        if ($numpat == 1) {
  1746. X            $descr = "Patch $patbase";
  1747. X            $has = "has"; $this = "this patch";
  1748. X            $patlist = $patbase;
  1749. X        } else {
  1750. X            $descr = "Patches $patbase thru " . ($patbase+$numpat-1);
  1751. X            $has = "have"; $this = "these patches";
  1752. X            $patlist = $patbase . "-" . ($patbase+$numpat-1);
  1753. X        }
  1754. X        $opt = ($mailer =~ /sendmail/) ? '-odq' : '';
  1755. X        open(MAILER, "|$mailer $opt $notify $cf'user");
  1756. X        print MAILER
  1757. X"To: $notify
  1758. XSubject: $descr for $package version $baserev $has been released.
  1759. XX-Mailer: dist [version $version PL$patchlevel]
  1760. X
  1761. XThis is just a quick note to let you know that $descr for $package
  1762. Xversion $baserev $has just been released. If you are actively using $package,
  1763. XI strongly suggest you upgrade by applying $this.
  1764. X
  1765. XYou can fetch $this automatically by sending me the following mail:
  1766. X
  1767. X    Subject: Command
  1768. X    @SH mailpatch - $package $baserev $patlist
  1769. X           ^ note the c
  1770. X
  1771. XIf you are not interested in receiving information about future patches,
  1772. Xplease send me the following mail:
  1773. X
  1774. X    Subject: Command
  1775. X    @SH package - $package $baserev
  1776. X
  1777. X-- patmake speaking for $maintname.
  1778. X";
  1779. X        close MAILER;
  1780. X    }
  1781. X}
  1782. X
  1783. Xsub usage {
  1784. X    print STDERR "Usage: patmake [-hV]\n";
  1785. X    print STDERR "  -h : print this message and exit\n";
  1786. X    print STDERR "  -V : print version number and exit\n";
  1787. X    exit 1;
  1788. X}
  1789. X
  1790. X!NO!SUBS!
  1791. X$grep -v '^;#' ../pl/package.pl >>patmake
  1792. X$grep -v '^;#' ../pl/users.pl >>patmake
  1793. Xchmod +x patmake
  1794. X$eunicefix patmake
  1795. END_OF_FILE
  1796.   if test 11622 -ne `wc -c <'pat/patmake.SH'`; then
  1797.     echo shar: \"'pat/patmake.SH'\" unpacked with wrong size!
  1798.   fi
  1799.   # end of 'pat/patmake.SH'
  1800. fi
  1801. if test -f 'pat/patsend.SH' -a "${1}" != "-c" ; then 
  1802.   echo shar: Will not clobber existing file \"'pat/patsend.SH'\"
  1803. else
  1804.   echo shar: Extracting \"'pat/patsend.SH'\" \(3190 characters\)
  1805.   sed "s/^X//" >'pat/patsend.SH' <<'END_OF_FILE'
  1806. Xcase $CONFIG in
  1807. X'')
  1808. X    if test -f config.sh; then TOP=.;
  1809. X    elif test -f ../config.sh; then TOP=..;
  1810. X    elif test -f ../../config.sh; then TOP=../..;
  1811. X    elif test -f ../../../config.sh; then TOP=../../..;
  1812. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  1813. X    else
  1814. X        (echo "Can't find config.sh."; exit 1)
  1815. X    fi
  1816. X    . $TOP/config.sh
  1817. X    ;;
  1818. Xesac
  1819. Xcase "$0" in
  1820. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  1821. Xesac
  1822. Xecho "Extracting pat/patsend (with variable substitutions)"
  1823. Xcat >patsend <<!GROK!THIS!
  1824. X$startperl
  1825. X    eval "exec perl -S \$0 \$*"
  1826. X        if \$running_under_some_shell;
  1827. X
  1828. X# $Id: patsend.SH,v 3.0 1993/08/18 12:10:49 ram Exp $
  1829. X#
  1830. X#  Copyright (c) 1991-1993, Raphael Manfredi
  1831. X#  
  1832. X#  You may redistribute only under the terms of the Artistic Licence,
  1833. X#  as specified in the README file that comes with the distribution.
  1834. X#  You may reuse parts of this distribution only within the terms of
  1835. X#  that same Artistic Licence; a copy of which may be found at the root
  1836. X#  of the source tree for dist 3.0.
  1837. X#
  1838. X# Original Author: Larry Wall <lwall@netlabs.com>
  1839. X#
  1840. X# $Log: patsend.SH,v $
  1841. X# Revision 3.0  1993/08/18  12:10:49  ram
  1842. X# Baseline for dist 3.0 netwide release.
  1843. X#
  1844. X
  1845. X\$orgname='$orgname';
  1846. X\$mailer='$mailer';
  1847. X\$version = '$VERSION';
  1848. X\$patchlevel = '$PATCHLEVEL';
  1849. X!GROK!THIS!
  1850. Xcat >>patsend <<'!NO!SUBS!'
  1851. X
  1852. Xrequire 'getopts.pl';
  1853. X&usage unless &Getopts("hV");
  1854. X
  1855. Xif ($opt_V) {
  1856. X    print STDERR "patsend $version PL$patchlevel\n";
  1857. X    exit 0;
  1858. X} elsif ($opt_h) {
  1859. X    &usage;
  1860. X}
  1861. X
  1862. X$RCSEXT = ',v' unless $RCSEXT;
  1863. Xchdir '..' if -d '../bugs';
  1864. X
  1865. X&readpackage;
  1866. X
  1867. Xchop($orgname = `cat $orgname`) if $orgname =~ m|^/|;
  1868. X
  1869. Xwhile ($_ = shift) {
  1870. X    if (/^(patch)?[1-9][\d,-]*$/) {
  1871. X        s/^patch//;
  1872. X        push(@argv,$_);
  1873. X    } else {
  1874. X        push(@dest,$_);
  1875. X    }
  1876. X}
  1877. X$dest = join(' ',@dest);
  1878. X&usage unless $dest;
  1879. X
  1880. X@ARGV = @argv;
  1881. X
  1882. Xopen(PL,"patchlevel.h") || die "Can't open patchlevel.h\n";
  1883. Xwhile (<PL>) {
  1884. X    $maxnum = $1 if /^#define\s+PATCHLEVEL\s+(\d+)/;
  1885. X}
  1886. Xclose PL;
  1887. Xdie "Malformed patchlevel.h file.\n" if $maxnum eq '';
  1888. X
  1889. Xif ($#ARGV < 0) {
  1890. X    $argv = $maxnum;
  1891. X    @ARGV = $argv;
  1892. X} else {
  1893. X    $argv = &rangeargs(@ARGV);
  1894. X    @ARGV = split(' ',$argv);
  1895. X}
  1896. X
  1897. X$argv =~ s/ $//;
  1898. X
  1899. Xif ($#ARGV < 0) {
  1900. X    print STDERR "No patches specified.\n";
  1901. X    &usage;
  1902. X} elsif ($#ARGV) {
  1903. X    print "Sending $package $baserev patches $argv to $dest...\n";
  1904. X} else {
  1905. X    print "Sending $package $baserev patch $argv to $dest...\n";
  1906. X}
  1907. X
  1908. Xfork && exit;
  1909. X
  1910. Xchdir 'bugs' || die "patsend: can't cd to bugs\n";
  1911. X
  1912. X$opt = '-odq' if $mailer =~ /sendmail/;
  1913. X
  1914. Xuntil ($#ARGV < 0) {
  1915. X    $patnum = shift;
  1916. X    open(XHEAD,">.xhead$$") || die "patsend: can't create temp file: $!\n";
  1917. X    print XHEAD
  1918. X"To: $dest
  1919. XSubject: $package $baserev patch #$patnum
  1920. XOrganization: $orgname
  1921. X
  1922. X
  1923. X[The latest patch for $package version $baserev is #$maxnum.]
  1924. X
  1925. X";
  1926. X    open(PATCH,"patch$patnum") || die "patsend: can't open patch$patnum: $!\n";
  1927. X    while (<PATCH>) {
  1928. X        print XHEAD;
  1929. X    }
  1930. X    close XHEAD;
  1931. X    system "$mailer $opt $dest <.xhead$$";
  1932. X}
  1933. Xunlink ".xhead$$";
  1934. X
  1935. Xsub usage {
  1936. X    print STDERR "Usage: patsend [-hV] [patchlist] [recipients]\n";
  1937. X    print STDERR "  -h : print this message and exit\n";
  1938. X    print STDERR "  -V : print version number and exit\n";
  1939. X    exit 1;
  1940. X}
  1941. X
  1942. X!NO!SUBS!
  1943. X$grep -v '^;#' ../pl/package.pl >>patsend
  1944. X$grep -v '^;#' ../pl/rangeargs.pl >>patsend
  1945. Xchmod +x patsend
  1946. X$eunicefix patsend
  1947. END_OF_FILE
  1948.   if test 3190 -ne `wc -c <'pat/patsend.SH'`; then
  1949.     echo shar: \"'pat/patsend.SH'\" unpacked with wrong size!
  1950.   fi
  1951.   # end of 'pat/patsend.SH'
  1952. fi
  1953. echo shar: End of archive 7 \(of 28\).
  1954. cp /dev/null ark7isdone
  1955. MISSING=""
  1956. for I 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 ; do
  1957.     if test ! -f ark${I}isdone ; then
  1958.     MISSING="${MISSING} ${I}"
  1959.     fi
  1960. done
  1961. if test "${MISSING}" = "" ; then
  1962.     echo You have unpacked all 28 archives.
  1963.     echo "Please run PACKNOTES through sh, read REAMDE and then type Configure."
  1964.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1965. else
  1966.     echo You still must unpack the following archives:
  1967.     echo "        " ${MISSING}
  1968. fi
  1969. exit 0
  1970.  
  1971. exit 0 # Just in case...
  1972.