home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / perl2 / patch1 / text0000.txt < prev   
Encoding:
Text File  |  1989-01-05  |  47.5 KB  |  1,575 lines

  1. [The latest patch for perl version 2.0 is #1.]
  2.  
  3. System: perl version 2.0
  4. Patch #: 1
  5. Priority: MEDIUM
  6. Subject: autoincrement of '' didn't work right.
  7. Subject: tr/x/y/ can dump core if y is shorter than x
  8. Subject: added support for DOSUID
  9. Subject: in Configure, fix for machines that can't do #/*undef
  10. Subject: in Configure, return code from ar was ignored
  11. Subject: in Configure, Cray uses bld instead of ar
  12. Subject: in Configure, Gnucpp adds space after symbol interpolation
  13. Subject: in Configure, grep '-i' should be grep '\-i'
  14. Subject: Configure should remove UU subdirectory entirely
  15. Subject: realclean now knows about ~ extension
  16. Subject: fixed some quotes in manual page
  17. Subject: clarified syntax of LIST in manual page
  18. Subject: clarified semantics of study in manual page
  19. Subject: added example of y with short second string in manual page
  20. Subject: added example of unlink with <*> in manual page
  21. Subject: removed redundant debugging code in regexp.c
  22.  
  23. Description:
  24.     If you used ++ on a variable that had the value '' (as opposed to
  25.     being undefined) it would increment the numeric part but not
  26.     invalidate the string part, which could then give false results.
  27.  
  28.     Berkeley recently sent out a patch that disables setuid #! scripts
  29.     because of an inherent problem in the semantics as they are
  30.     currently defined.  If you have installed that patch, your setuid
  31.     and setgid bits are useless on scripts.  I've added a means
  32.     for perl to examine those bits and emulate setuid/setgid scripts
  33.     itself in what I believe is a secure manner.  If normal perl
  34.     detects such a script, it passes it off to another version of
  35.     perl that runs setuid root, and can run the script under the
  36.     desired uid/gid.  This feature is optional, and Configure will
  37.     ask if you want to do it.
  38.  
  39.     Some machines didn't like config.h when it said #/*undef SYMBOL.
  40.     Config.h.SH now is smart enough to tuck the # inside the comment.
  41.  
  42.     There were several small problems in Configure: the return code from
  43.     ar was hidden by a piped call to sed, so if ar failed it went
  44.     undetected.  The Cray uses a program called bld instead of ar.
  45.     Let's hear it for compatibilty.  At least one version of gnucpp
  46.     adds a space after symbol interpolation, which was giving the
  47.     C preprocessor detector fits.  There was a call to grep '-i' that
  48.     needed to have the -i protected by a backslash.  Also, Configure
  49.     should remove the UU subdirectory that it makes while running.
  50.  
  51.     "make realclean" now knows about the alternate patch extension ~.
  52.  
  53.     In the manual page, I fixed some quotes that were ugly in troff,
  54.     and did some clarification of LIST, study, tr and unlink.
  55.  
  56.     regexp.c had some redundant debugging code.
  57.  
  58.     tr/x/y/ could dump core if y is shorter than x.  I found this out
  59.     when I tried translating a bunch of characters to space by saying
  60.     something like y/a-z/ /.
  61.  
  62. Fix:    From rn, say "| patch -p -N -d DIR", where DIR is your perl source
  63.     directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
  64.     If you don't have the patch program, apply the following by hand,
  65.     or get patch (version 2.0, latest patchlevel).
  66.  
  67.     After patching:
  68.         Configure
  69.         make depend
  70.         make
  71.         make test
  72.         make install
  73.  
  74.     If patch indicates that patchlevel is the wrong version, you may need
  75.     to apply one or more previous patches, or the patch may already
  76.     have been applied.  See the patchlevel.h file to find out what has or
  77.     has not been applied.  In any event, don't continue with the patch.
  78.  
  79.     If you are missing previous patches they can be obtained from me:
  80.  
  81.     Larry Wall
  82.     lwall@jpl-devvax.jpl.nasa.gov
  83.  
  84.     If you send a mail message of the following form it will greatly speed
  85.     processing:
  86.  
  87.     Subject: Command
  88.     @SH mailpatch PATH perl 2.0 LIST
  89.            ^ note the c
  90.  
  91.     where PATH is a return path FROM ME TO YOU either in Internet notation,
  92.     or in bang notation from some well-known host, and LIST is the number
  93.     of one or more patches you need, separated by spaces, commas, and/or
  94.     hyphens.  Saying 35- says everything from 35 to the end.
  95.  
  96.     You can also get the patches via anonymous FTP from
  97.     jpl-devvax.jpl.nasa.gov (128.149.8.43).
  98.  
  99. Index: patchlevel.h
  100. Prereq: 0
  101. 1c1
  102. < #define PATCHLEVEL 0
  103. ---
  104. > #define PATCHLEVEL 1
  105.  
  106. Index: Configure
  107. Prereq: 2.0
  108. *** Configure.old    Tue Jun 28 16:40:03 1988
  109. --- Configure    Tue Jun 28 16:40:04 1988
  110. ***************
  111. *** 8,14 ****
  112.   # and edit it to reflect your system.  Some packages may include samples
  113.   # of config.h for certain machines, so you might look for one of those.)
  114.   #
  115. ! # $Header: Configure,v 2.0 88/06/05 00:07:37 root Exp $
  116.   #
  117.   # Yes, you may rip this off to use in other distribution packages.
  118.   # (Note: this Configure script was generated automatically.  Rather than
  119. --- 8,14 ----
  120.   # and edit it to reflect your system.  Some packages may include samples
  121.   # of config.h for certain machines, so you might look for one of those.)
  122.   #
  123. ! # $Header: Configure,v 2.0.1.1 88/06/28 16:24:02 root Exp $
  124.   #
  125.   # Yes, you may rip this off to use in other distribution packages.
  126.   # (Note: this Configure script was generated automatically.  Rather than
  127. ***************
  128. *** 76,81 ****
  129. --- 76,82 ----
  130.   d_bcopy=''
  131.   d_charsprf=''
  132.   d_crypt=''
  133. + d_dosuid=''
  134.   d_fchmod=''
  135.   d_fchown=''
  136.   d_getgrps=''
  137. ***************
  138. *** 124,130 ****
  139.   defvoidused=''
  140.   privlib=''
  141.   CONFIG=''
  142.   : set package name
  143.   package=perl
  144.   
  145. --- 125,130 ----
  146. ***************
  147. *** 134,140 ****
  148.   echo " "
  149.   
  150.   define='define'
  151. ! undef='/*undef'
  152.   libpth='/usr/lib /usr/local/lib /lib'
  153.   smallmach='pdp11 i8086 z8000 i80286 iAPX286'
  154.   rmlist='kit[1-9]isdone kit[1-9][0-9]isdone'
  155. --- 134,140 ----
  156.   echo " "
  157.   
  158.   define='define'
  159. ! undef='undef'
  160.   libpth='/usr/lib /usr/local/lib /lib'
  161.   smallmach='pdp11 i8086 z8000 i80286 iAPX286'
  162.   rmlist='kit[1-9]isdone kit[1-9][0-9]isdone'
  163. ***************
  164. *** 480,490 ****
  165.       echo " "
  166.       echo "nm didn't seem to work right."
  167.       echo "Trying ar instead..."
  168. !     if ar t $libc | sed -e 's/\.o$//' > libc.list; then
  169.           echo "Ok."
  170.       else
  171. !         echo "That didn't work either.  Giving up."
  172. !         exit 1
  173.       fi
  174.       fi
  175.   fi
  176. --- 480,498 ----
  177.       echo " "
  178.       echo "nm didn't seem to work right."
  179.       echo "Trying ar instead..."
  180. !     rmlist="$rmlist libc.tmp"
  181. !     if ar t $libc > libc.tmp; then
  182. !         sed -e 's/\.o$//' < libc.tmp > libc.list
  183.           echo "Ok."
  184.       else
  185. !         echo "ar didn't seem to work right."
  186. !         echo "Maybe this is a Cray...trying bld instead..."
  187. !         if bld t $libc | sed -e 's/.*\///' -e 's/\.o:.*$//' > libc.list; then
  188. !         echo "Ok."
  189. !         else
  190. !             echo "That didn't work either.  Giving up."
  191. !             exit 1
  192. !         fi
  193.       fi
  194.       fi
  195.   fi
  196. ***************
  197. *** 621,627 ****
  198.   EOT
  199.   echo 'Maybe "'$cpp'" will work...'
  200.   $cpp <testcpp.c >testcpp.out 2>&1
  201. ! if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  202.       echo "Yup, it does."
  203.       cppstdin="$cpp"
  204.       cppminus='';
  205. --- 629,635 ----
  206.   EOT
  207.   echo 'Maybe "'$cpp'" will work...'
  208.   $cpp <testcpp.c >testcpp.out 2>&1
  209. ! if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  210.       echo "Yup, it does."
  211.       cppstdin="$cpp"
  212.       cppminus='';
  213. ***************
  214. *** 628,634 ****
  215.   else
  216.       echo 'Nope, maybe "'$cpp' -" will work...'
  217.       $cpp - <testcpp.c >testcpp.out 2>&1
  218. !     if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  219.       echo "Yup, it does."
  220.       cppstdin="$cpp"
  221.       cppminus='-';
  222. --- 636,642 ----
  223.   else
  224.       echo 'Nope, maybe "'$cpp' -" will work...'
  225.       $cpp - <testcpp.c >testcpp.out 2>&1
  226. !     if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  227.       echo "Yup, it does."
  228.       cppstdin="$cpp"
  229.       cppminus='-';
  230. ***************
  231. *** 635,641 ****
  232.       else
  233.       echo 'No such luck...maybe "cc -E" will work...'
  234.       cc -E <testcpp.c >testcpp.out 2>&1
  235. !     if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  236.           echo "It works!"
  237.           cppstdin='cc -E'
  238.           cppminus='';
  239. --- 643,649 ----
  240.       else
  241.       echo 'No such luck...maybe "cc -E" will work...'
  242.       cc -E <testcpp.c >testcpp.out 2>&1
  243. !     if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  244.           echo "It works!"
  245.           cppstdin='cc -E'
  246.           cppminus='';
  247. ***************
  248. *** 642,648 ****
  249.       else
  250.           echo 'Nixed again...maybe "cc -E -" will work...'
  251.           cc -E - <testcpp.c >testcpp.out 2>&1
  252. !         if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  253.           echo "Hooray, it works!  I was beginning to wonder."
  254.           cppstdin='cc -E'
  255.           cppminus='-';
  256. --- 650,656 ----
  257.       else
  258.           echo 'Nixed again...maybe "cc -E -" will work...'
  259.           cc -E - <testcpp.c >testcpp.out 2>&1
  260. !         if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  261.           echo "Hooray, it works!  I was beginning to wonder."
  262.           cppstdin='cc -E'
  263.           cppminus='-';
  264. ***************
  265. *** 649,655 ****
  266.           else
  267.           echo 'Nope...maybe "cc -P" will work...'
  268.           cc -P <testcpp.c >testcpp.out 2>&1
  269. !         if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  270.               echo "Yup, that does."
  271.               cppstdin='cc -P'
  272.               cppminus='';
  273. --- 657,663 ----
  274.           else
  275.           echo 'Nope...maybe "cc -P" will work...'
  276.           cc -P <testcpp.c >testcpp.out 2>&1
  277. !         if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  278.               echo "Yup, that does."
  279.               cppstdin='cc -P'
  280.               cppminus='';
  281. ***************
  282. *** 656,662 ****
  283.           else
  284.               echo 'Nope...maybe "cc -P -" will work...'
  285.               cc -P - <testcpp.c >testcpp.out 2>&1
  286. !             if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  287.               echo "Yup, that does."
  288.               cppstdin='cc -P'
  289.               cppminus='-';
  290. --- 664,670 ----
  291.           else
  292.               echo 'Nope...maybe "cc -P -" will work...'
  293.               cc -P - <testcpp.c >testcpp.out 2>&1
  294. !             if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  295.               echo "Yup, that does."
  296.               cppstdin='cc -P'
  297.               cppminus='-';
  298. ***************
  299. *** 666,672 ****
  300.               '') ;;
  301.               *) $cppstdin $cppminus <testcpp.c >testcpp.out 2>&1;;
  302.               esac
  303. !             if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  304.                   echo "Hooray, you did!  I was beginning to wonder."
  305.               else
  306.                   echo 'Uh-uh.  Time to get fancy...'
  307. --- 674,680 ----
  308.               '') ;;
  309.               *) $cppstdin $cppminus <testcpp.c >testcpp.out 2>&1;;
  310.               esac
  311. !             if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  312.                   echo "Hooray, you did!  I was beginning to wonder."
  313.               else
  314.                   echo 'Uh-uh.  Time to get fancy...'
  315. ***************
  316. *** 674,680 ****
  317.                   cppstdin='(cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
  318.                   cppminus='';
  319.                   $cppstdin <testcpp.c >testcpp.out 2>&1
  320. !                 if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  321.                   echo "Eureka!."
  322.                   else
  323.                   dflt=blurfl
  324. --- 682,688 ----
  325.                   cppstdin='(cat >/tmp/$$.c; cc -E /tmp/$$.c; rm /tmp/$$.c)'
  326.                   cppminus='';
  327.                   $cppstdin <testcpp.c >testcpp.out 2>&1
  328. !                 if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  329.                   echo "Eureka!."
  330.                   else
  331.                   dflt=blurfl
  332. ***************
  333. *** 683,689 ****
  334.                   . myread
  335.                   cppstdin="$ans"
  336.                   $cppstdin <testcpp.c >testcpp.out 2>&1
  337. !                 if $contains 'abc.xyz' testcpp.out >/dev/null 2>&1 ; then
  338.                       echo "OK, that will do."
  339.                   else
  340.                       echo "Sorry, I can't get that to work.  Go find one."
  341. --- 691,697 ----
  342.                   . myread
  343.                   cppstdin="$ans"
  344.                   $cppstdin <testcpp.c >testcpp.out 2>&1
  345. !                 if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  346.                       echo "OK, that will do."
  347.                   else
  348.                       echo "Sorry, I can't get that to work.  Go find one."
  349. ***************
  350. *** 733,738 ****
  351. --- 741,777 ----
  352.       d_crypt="$undef"
  353.   fi
  354.   
  355. + : now see if they want to do setuid emulation
  356. + case "$d_dosuid" in
  357. + '') if bsd; then
  358. +     dflt=y
  359. +     else
  360. +     dflt=n
  361. +     fi
  362. +     ;;
  363. + *undef*) dflt=n;;
  364. + *) dflt=y;;
  365. + esac
  366. + cat <<EOM
  367. +  
  368. + Some sites have disabled setuid #! scripts because of a bug in the kernel
  369. + that prevents them from being secure.  If you are on such a system, the
  370. + setuid/setgid bits on scripts are currently useless.  It is possible for
  371. + $package to detect those bits and emulate setuid/setgid in a secure fashion
  372. + until a better solution is devised for the kernel problem.
  373. + EOM
  374. + rp="Do you want to do setuid/setgid emulation? [$dflt]"
  375. + echo $n "$rp $c"
  376. + . myread
  377. + case "$ans" in
  378. + '') $ans="$dflt";;
  379. + esac
  380. + case "$ans" in
  381. + y*)  d_dosuid="$define";;
  382. + *) d_dosuid="$undef";;
  383. + esac
  384.   : see if fchmod exists
  385.   echo " "
  386.   if $contains '^fchmod$' libc.list >/dev/null 2>&1; then
  387. ***************
  388. *** 1334,1341 ****
  389.   *split)
  390.       case "$split" in
  391.       '') 
  392. !     if $contains '-i' $mansrc/ld.1 >/dev/null 2>&1 || \
  393. !        $contains '-i' $mansrc/cc.1 >/dev/null 2>&1; then
  394.           dflt='-i'
  395.       else
  396.           dflt='none'
  397. --- 1373,1380 ----
  398.   *split)
  399.       case "$split" in
  400.       '') 
  401. !     if $contains '\-i' $mansrc/ld.1 >/dev/null 2>&1 || \
  402. !        $contains '\-i' $mansrc/cc.1 >/dev/null 2>&1; then
  403.           dflt='-i'
  404.       else
  405.           dflt='none'
  406. ***************
  407. *** 1594,1599 ****
  408. --- 1633,1639 ----
  409.   d_bcopy='$d_bcopy'
  410.   d_charsprf='$d_charsprf'
  411.   d_crypt='$d_crypt'
  412. + d_dosuid='$d_dosuid'
  413.   d_fchmod='$d_fchmod'
  414.   d_fchown='$d_fchown'
  415.   d_getgrps='$d_getgrps'
  416. ***************
  417. *** 1643,1649 ****
  418.   privlib='$privlib'
  419.   CONFIG=true
  420.   EOT
  421. !  
  422.   CONFIG=true
  423.   
  424.   echo " "
  425. --- 1683,1689 ----
  426.   privlib='$privlib'
  427.   CONFIG=true
  428.   EOT
  429.   CONFIG=true
  430.   
  431.   echo " "
  432. ***************
  433. *** 1716,1720 ****
  434. --- 1756,1763 ----
  435.   fi
  436.   
  437.   $rm -f kit*isdone
  438. + : the following is currently useless
  439.   cd UU && $rm -f $rmlist
  440. + : since this removes it all anyway
  441. + cd .. && $rm -rf UU
  442.   : end of Configure
  443.  
  444. Index: Makefile.SH
  445. Prereq: 2.0
  446. *** Makefile.SH.old    Tue Jun 28 16:40:14 1988
  447. --- Makefile.SH    Tue Jun 28 16:40:15 1988
  448. ***************
  449. *** 18,28 ****
  450.   *) sln='ln';;
  451.   esac
  452.   
  453.   echo "Extracting Makefile (with variable substitutions)"
  454.   cat >Makefile <<!GROK!THIS!
  455. ! # $Header: Makefile.SH,v 2.0 88/06/05 00:07:54 root Exp $
  456.   #
  457.   # $Log:    Makefile.SH,v $
  458.   # Revision 2.0  88/06/05  00:07:54  root
  459.   # Baseline version 2.0.
  460.   # 
  461. --- 18,37 ----
  462.   *) sln='ln';;
  463.   esac
  464.   
  465. + case "$d_dosuid" in
  466. + *define*) suidperl='suidperl' ;;
  467. + *) suidperl='';;
  468. + esac
  469.   echo "Extracting Makefile (with variable substitutions)"
  470.   cat >Makefile <<!GROK!THIS!
  471. ! # $Header: Makefile.SH,v 2.0.1.1 88/06/28 16:26:04 root Exp $
  472.   #
  473.   # $Log:    Makefile.SH,v $
  474. + # Revision 2.0.1.1  88/06/28  16:26:04  root
  475. + # patch1: support for DOSUID
  476. + # patch1: realclean now knows about ~ extension
  477. + # 
  478.   # Revision 2.0  88/06/05  00:07:54  root
  479.   # Baseline version 2.0.
  480.   # 
  481. ***************
  482. *** 42,53 ****
  483.   SLN = $sln
  484.   
  485.   libs = $libnm -lm
  486. - !GROK!THIS!
  487.   
  488. ! cat >>Makefile <<'!NO!SUBS!'
  489.   
  490. ! public = perl perldb
  491.   
  492.   private = 
  493.   
  494.   manpages = perl.man perldb.man
  495. --- 51,62 ----
  496.   SLN = $sln
  497.   
  498.   libs = $libnm -lm
  499.   
  500. ! public = perl perldb $suidperl
  501.   
  502. ! !GROK!THIS!
  503.   
  504. + cat >>Makefile <<'!NO!SUBS!'
  505.   private = 
  506.   
  507.   manpages = perl.man perldb.man
  508. ***************
  509. *** 67,73 ****
  510.   c = $(c1) $(c2)
  511.   
  512.   obj1 = arg.o array.o cmd.o dump.o eval.o form.o hash.o $(mallocobj)
  513. ! obj2 = perly.o regexp.o stab.o str.o toke.o util.o version.o
  514.   
  515.   obj = $(obj1) $(obj2)
  516.   
  517. --- 76,82 ----
  518.   c = $(c1) $(c2)
  519.   
  520.   obj1 = arg.o array.o cmd.o dump.o eval.o form.o hash.o $(mallocobj)
  521. ! obj2 = regexp.o stab.o str.o toke.o util.o version.o
  522.   
  523.   obj = $(obj1) $(obj2)
  524.   
  525. ***************
  526. *** 84,92 ****
  527.   all: $(public) $(private) $(util)
  528.       touch all
  529.   
  530. ! perl: $(obj) perl.o
  531. !     $(CC) $(LDFLAGS) $(LARGE) $(obj) perl.o $(libs) -o perl
  532.   
  533.   perl.c perly.h: perl.y
  534.       @ echo Expect 37 shift/reduce errors...
  535.       yacc -d perl.y
  536. --- 93,121 ----
  537.   all: $(public) $(private) $(util)
  538.       touch all
  539.   
  540. ! perl: perly.o $(obj) perl.o
  541. !     $(CC) $(LDFLAGS) $(LARGE) perly.o $(obj) perl.o $(libs) -o perl
  542.   
  543. + !NO!SUBS!
  544. + case "$d_dosuid" in
  545. + *define*)
  546. +     cat >>Makefile <<'!NO!SUBS!'
  547. + suidperl: sperly.o $(obj) perl.o
  548. +     $(CC) $(LDFLAGS) $(LARGE) sperly.o $(obj) perl.o $(libs) -o suidperl
  549. + sperly.o: perly.c
  550. +     /bin/rm -f sperly.c
  551. +     ln perly.c sperly.c
  552. +     $(CC) -c -DIAMSUID $(CFLAGS) $(LARGE) sperly.c
  553. +     /bin/rm -f sperly.c
  554. + !NO!SUBS!
  555. +     ;;
  556. + esac
  557. + cat >>Makefile <<'!NO!SUBS!'
  558.   perl.c perly.h: perl.y
  559.       @ echo Expect 37 shift/reduce errors...
  560.       yacc -d perl.y
  561. ***************
  562. *** 108,117 ****
  563.       export PATH || exit 1
  564.       - mv $(bin)/perl $(bin)/perl.old 2>/dev/null
  565.       - if test `pwd` != $(bin); then cp $(public) $(bin); fi
  566. !     cd $(bin); \
  567.   for pub in $(public); do \
  568.   chmod +x `basename $$pub`; \
  569.   done
  570.       - test $(bin) = /usr/bin || rm -f /usr/bin/perl
  571.       - test $(bin) = /usr/bin || $(SLN) $(bin)/perl /usr/bin || cp $(bin)/perl /usr/bin
  572.       chmod +x makedir
  573. --- 137,157 ----
  574.       export PATH || exit 1
  575.       - mv $(bin)/perl $(bin)/perl.old 2>/dev/null
  576.       - if test `pwd` != $(bin); then cp $(public) $(bin); fi
  577. !     - cd $(bin); \
  578.   for pub in $(public); do \
  579.   chmod +x `basename $$pub`; \
  580.   done
  581. + !NO!SUBS!
  582. + case "$d_dosuid" in
  583. + *define*)
  584. +     cat >>Makefile <<'!NO!SUBS!'
  585. +     - chmod 4711 $(bin)/suidperl 2>/dev/null
  586. + !NO!SUBS!
  587. +     ;;
  588. + esac
  589. + cat >>Makefile <<'!NO!SUBS!'
  590.       - test $(bin) = /usr/bin || rm -f /usr/bin/perl
  591.       - test $(bin) = /usr/bin || $(SLN) $(bin)/perl /usr/bin || cp $(bin)/perl /usr/bin
  592.       chmod +x makedir
  593. ***************
  594. *** 134,140 ****
  595.       rm -f *.o
  596.   
  597.   realclean:
  598. !     rm -f perl *.orig */*.orig *.o core $(addedbyconf)
  599.   
  600.   # The following lint has practically everything turned on.  Unfortunately,
  601.   # you have to wade through a lot of mumbo jumbo that can't be suppressed.
  602. --- 174,180 ----
  603.       rm -f *.o
  604.   
  605.   realclean:
  606. !     rm -f perl *.orig */*.orig *~ */*~ *.o core $(addedbyconf)
  607.   
  608.   # The following lint has practically everything turned on.  Unfortunately,
  609.   # you have to wade through a lot of mumbo jumbo that can't be suppressed.
  610. ***************
  611. *** 163,169 ****
  612.       echo $(sh) | tr ' ' '\012' >.shlist
  613.   
  614.   # AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
  615. ! $(obj):
  616.       @ echo "You haven't done a "'"make depend" yet!'; exit 1
  617.   makedepend: makedepend.SH
  618.       /bin/sh makedepend.SH
  619. --- 203,209 ----
  620.       echo $(sh) | tr ' ' '\012' >.shlist
  621.   
  622.   # AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
  623. ! perly.o $(obj):
  624.       @ echo "You haven't done a "'"make depend" yet!'; exit 1
  625.   makedepend: makedepend.SH
  626.       /bin/sh makedepend.SH
  627.  
  628. Index: config.h.SH
  629. *** config.h.SH.old    Tue Jun 28 16:40:19 1988
  630. --- config.h.SH    Tue Jun 28 16:40:20 1988
  631. ***************
  632. *** 11,17 ****
  633.       ;;
  634.   esac
  635.   echo "Extracting config.h (with variable substitutions)"
  636. ! cat <<!GROK!THIS! >config.h
  637.   /* config.h
  638.    * This file was produced by running the config.h.SH script, which
  639.    * gets its values from config.sh, which is generally produced by
  640. --- 11,17 ----
  641.       ;;
  642.   esac
  643.   echo "Extracting config.h (with variable substitutions)"
  644. ! sed <<!GROK!THIS! >config.h -e 's!^#undef!/\*#undef!'
  645.   /* config.h
  646.    * This file was produced by running the config.h.SH script, which
  647.    * gets its values from config.sh, which is generally produced by
  648. ***************
  649. *** 70,75 ****
  650. --- 70,90 ----
  651.    *    to encrypt passwords and the like.
  652.    */
  653.   #$d_crypt    CRYPT        /**/
  654. + /* DOSUID:
  655. +  *    This symbol, if defined, indicates that the C program should
  656. +  *    check the script that it is executing for setuid/setgid bits, and
  657. +  *    attempt to emulate setuid/setgid on systems that have disabled
  658. +  *    setuid #! scripts because the kernel can't do it securely.
  659. +  *    It is up to the package designer to make sure that this emulation
  660. +  *    is done securely.  Among other things, it should do an fstat on
  661. +  *    the script it just opened to make sure it really is a setuid/setgid
  662. +  *    script, it should make sure the arguments passed correspond exactly
  663. +  *    to the argument on the #! line, and it should not trust any
  664. +  *    subprocesses to which it must pass the filename rather than the
  665. +  *    file descriptor of the script to be executed.
  666. +  */
  667. + #$d_dosuid DOSUID        /**/
  668.   
  669.   /* FCHMOD:
  670.    *    This symbol, if defined, indicates that the fchmod routine is available
  671.  
  672. Index: perl.man.1
  673. Prereq: 2.0
  674. *** perl.man.1.old    Tue Jun 28 16:40:27 1988
  675. --- perl.man.1    Tue Jun 28 16:40:29 1988
  676. ***************
  677. *** 1,7 ****
  678.   .rn '' }`
  679. ! ''' $Header: perl.man.1,v 2.0 88/06/05 00:09:23 root Exp $
  680.   ''' 
  681.   ''' $Log:    perl.man.1,v $
  682.   ''' Revision 2.0  88/06/05  00:09:23  root
  683.   ''' Baseline version 2.0.
  684.   ''' 
  685. --- 1,11 ----
  686.   .rn '' }`
  687. ! ''' $Header: perl.man.1,v 2.0.1.1 88/06/28 16:28:09 root Exp $
  688.   ''' 
  689.   ''' $Log:    perl.man.1,v $
  690. + ''' Revision 2.0.1.1  88/06/28  16:28:09  root
  691. + ''' patch1: fixed some quotes
  692. + ''' patch1: clarified syntax of LIST
  693. + ''' 
  694.   ''' Revision 2.0  88/06/05  00:09:23  root
  695.   ''' Baseline version 2.0.
  696.   ''' 
  697. ***************
  698. *** 292,298 ****
  699.   .TP 5
  700.   .B \-U
  701.   allows perl to do unsafe operations.
  702. ! Currently the only "unsafe" operation is the unlinking of directories while
  703.   running as superuser.
  704.   .TP 5
  705.   .B \-v
  706. --- 296,302 ----
  707.   .TP 5
  708.   .B \-U
  709.   allows perl to do unsafe operations.
  710. ! Currently the only \*(L"unsafe\*(R" operation is the unlinking of directories while
  711.   running as superuser.
  712.   .TP 5
  713.   .B \-v
  714. ***************
  715. *** 731,738 ****
  716.   .PP
  717.   The foreach loop iterates over a normal array value and sets the variable
  718.   VAR to be each element of the array in turn.
  719. ! The "foreach" keyword is actually identical to the "for" keyword,
  720. ! so you can use "foreach" for readability or "for" for brevity.
  721.   If VAR is omitted, $_ is set to each value.
  722.   If ARRAY is an actual array (as opposed to an expression returning an array
  723.   value), you can modify each element of the array
  724. --- 735,742 ----
  725.   .PP
  726.   The foreach loop iterates over a normal array value and sets the variable
  727.   VAR to be each element of the array in turn.
  728. ! The \*(L"foreach\*(R" keyword is actually identical to the \*(L"for\*(R" keyword,
  729. ! so you can use \*(L"foreach\*(R" for readability or \*(L"for\*(R" for brevity.
  730.   If VAR is omitted, $_ is set to each value.
  731.   If ARRAY is an actual array (as opposed to an expression returning an array
  732.   value), you can modify each element of the array
  733. ***************
  734. *** 909,916 ****
  735.   (It doesn't become false till the next time the range operator evaluated.
  736.   It can become false on the same evaluation it became true, but it still returns
  737.   true once.)
  738. ! The right operand is not evaluated while the operator is in the "false" state,
  739. ! and the left operand is not evaluated while the operator is in the "true" state.
  740.   The .. operator is primarily intended for doing line number ranges after
  741.   the fashion of \fIsed\fR or \fIawk\fR.
  742.   The precedence is a little lower than || and &&.
  743. --- 913,920 ----
  744.   (It doesn't become false till the next time the range operator evaluated.
  745.   It can become false on the same evaluation it became true, but it still returns
  746.   true once.)
  747. ! The right operand is not evaluated while the operator is in the \*(L"false\*(R" state,
  748. ! and the left operand is not evaluated while the operator is in the \*(L"true\*(R" state.
  749.   The .. operator is primarily intended for doing line number ranges after
  750.   the fashion of \fIsed\fR or \fIawk\fR.
  751.   The precedence is a little lower than || and &&.
  752. ***************
  753. *** 1057,1062 ****
  754. --- 1061,1067 ----
  755.   Such a list can consist of any combination of scalar arguments or arrays;
  756.   the arrays will be included in the list as if each individual element were
  757.   interpolated at that point in the list.
  758. + Elements of the LIST should be separated by commas.
  759.   .Ip "/PATTERN/i" 8 4
  760.   Searches a string for a pattern, and returns true (1) or false ('').
  761.   If no string is specified via the =~ or !~ operator,
  762. ***************
  763. *** 1234,1242 ****
  764.   If the value of EXPR does not end in a newline, the current script line
  765.   number and input line number (if any) are also printed, and a newline is
  766.   supplied.
  767. ! Hint: sometimes appending ", stopped" to your message will cause it to make
  768. ! better sense when the string "at foo line 123" is appended.
  769. ! Suppose you are running script "canasta".
  770.   .nf
  771.   
  772.   .ne 7
  773. --- 1239,1247 ----
  774.   If the value of EXPR does not end in a newline, the current script line
  775.   number and input line number (if any) are also printed, and a newline is
  776.   supplied.
  777. ! Hint: sometimes appending \*(L", stopped\*(R" to your message will cause it to make
  778. ! better sense when the string \*(L"at foo line 123\*(R" is appended.
  779. ! Suppose you are running script \*(L"canasta\*(R".
  780.   .nf
  781.   
  782.   .ne 7
  783. ***************
  784. *** 1267,1273 ****
  785.   (See the section on subroutines later on.)
  786.   SUBROUTINE may be a scalar variable, in which case the variable contains
  787.   the name of the subroutine to execute.
  788. ! The parentheses are required to avoid confusion with the next form of "do".
  789.   .Ip "do EXPR" 8 3
  790.   Uses the value of EXPR as a filename and executes the contents of the file
  791.   as a perl script.
  792. --- 1272,1278 ----
  793.   (See the section on subroutines later on.)
  794.   SUBROUTINE may be a scalar variable, in which case the variable contains
  795.   the name of the subroutine to execute.
  796. ! The parentheses are required to avoid confusion with the next form of \*(L"do\*(R".
  797.   .Ip "do EXPR" 8 3
  798.   Uses the value of EXPR as a filename and executes the contents of the file
  799.   as a perl script.
  800. ***************
  801. *** 1287,1293 ****
  802.   call it, so if you are going to use the file inside a loop you might prefer
  803.   to use #include, at the expense of a little more startup time.
  804.   (The main problem with #include is that cpp doesn't grok # comments--a
  805. ! workaround is to use ";#" for standalone comments.)
  806.   Note that the following are NOT equivalent:
  807.   .nf
  808.   
  809. --- 1292,1298 ----
  810.   call it, so if you are going to use the file inside a loop you might prefer
  811.   to use #include, at the expense of a little more startup time.
  812.   (The main problem with #include is that cpp doesn't grok # comments--a
  813. ! workaround is to use \*(L";#\*(R" for standalone comments.)
  814.   Note that the following are NOT equivalent:
  815.   .nf
  816.   
  817.  
  818. Index: perl.man.2
  819. Prereq: 2.0
  820. *** perl.man.2.old    Tue Jun 28 16:40:37 1988
  821. --- perl.man.2    Tue Jun 28 16:40:39 1988
  822. ***************
  823. *** 1,7 ****
  824.   ''' Beginning of part 2
  825. ! ''' $Header: perl.man.2,v 2.0 88/06/05 00:09:30 root Exp $
  826.   '''
  827.   ''' $Log:    perl.man.2,v $
  828.   ''' Revision 2.0  88/06/05  00:09:30  root
  829.   ''' Baseline version 2.0.
  830.   ''' 
  831. --- 1,13 ----
  832.   ''' Beginning of part 2
  833. ! ''' $Header: perl.man.2,v 2.0.1.1 88/06/28 16:31:49 root Exp $
  834.   '''
  835.   ''' $Log:    perl.man.2,v $
  836. + ''' Revision 2.0.1.1  88/06/28  16:31:49  root
  837. + ''' patch1: fixed some quotes
  838. + ''' patch1: clarified semantics of study
  839. + ''' patch1: added example of y with short second string
  840. + ''' patch1: added example of unlink with <*>
  841. + ''' 
  842.   ''' Revision 2.0  88/06/05  00:09:30  root
  843.   ''' Baseline version 2.0.
  844.   ''' 
  845. ***************
  846. *** 99,105 ****
  847.   .Ip "local(LIST)" 8 4
  848.   Declares the listed (scalar) variables to be local to the enclosing block,
  849.   subroutine or eval.
  850. ! (The "do 'filename';" operator also counts as an eval.)
  851.   This operator works by saving the current values of those variables in LIST
  852.   on a hidden stack and restoring them upon exiting the block, subroutine or eval.
  853.   The LIST may be assigned to if desired, which allows you to initialize
  854. --- 105,111 ----
  855.   .Ip "local(LIST)" 8 4
  856.   Declares the listed (scalar) variables to be local to the enclosing block,
  857.   subroutine or eval.
  858. ! (The \*(L"do 'filename';\*(R" operator also counts as an eval.)
  859.   This operator works by saving the current values of those variables in LIST
  860.   on a hidden stack and restoring them upon exiting the block, subroutine or eval.
  861.   The LIST may be assigned to if desired, which allows you to initialize
  862. ***************
  863. *** 226,232 ****
  864.   
  865.   .fi
  866.   You may also, in the Bourne shell tradition, specify an EXPR beginning
  867. ! with ">&", in which case the rest of the string
  868.   is interpreted as the name of a filehandle
  869.   (or file descriptor, if numeric) which is to be duped and opened.
  870.   Here is a script that saves, redirects, and restores stdout and stdin:
  871. --- 232,238 ----
  872.   
  873.   .fi
  874.   You may also, in the Bourne shell tradition, specify an EXPR beginning
  875. ! with \*(L">&\*(R", in which case the rest of the string
  876.   is interpreted as the name of a filehandle
  877.   (or file descriptor, if numeric) which is to be duped and opened.
  878.   Here is a script that saves, redirects, and restores stdout and stdin:
  879. ***************
  880. *** 256,262 ****
  881.       print stderr "stderr 2\en";
  882.   
  883.   .fi
  884. ! If you open a pipe on the command "-", i.e. either "|-" or "-|",
  885.   then there is an implicit fork done, and the return value of open
  886.   is the pid of the child within the parent process, and 0 within the child
  887.   process.
  888. --- 262,268 ----
  889.       print stderr "stderr 2\en";
  890.   
  891.   .fi
  892. ! If you open a pipe on the command \*(L"-\*(R", i.e. either \*(L"|-\*(R" or \*(L"-|\*(R",
  893.   then there is an implicit fork done, and the return value of open
  894.   is the pid of the child within the parent process, and 0 within the child
  895.   process.
  896. ***************
  897. *** 304,310 ****
  898.   To set the default output channel to something other than stdout use the select operation.
  899.   .Ip "printf FILEHANDLE LIST" 8 9
  900.   .Ip "printf LIST" 8
  901. ! Equivalent to a "print FILEHANDLE sprintf(LIST)".
  902.   .Ip "push(ARRAY,LIST)" 8 7
  903.   Treats ARRAY (@ is optional) as a stack, and pushes the values of LIST
  904.   onto the end of ARRAY.
  905. --- 310,316 ----
  906.   To set the default output channel to something other than stdout use the select operation.
  907.   .Ip "printf FILEHANDLE LIST" 8 9
  908.   .Ip "printf LIST" 8
  909. ! Equivalent to a \*(L"print FILEHANDLE sprintf(LIST)\*(R".
  910.   .Ip "push(ARRAY,LIST)" 8 7
  911.   Treats ARRAY (@ is optional) as a stack, and pushes the values of LIST
  912.   onto the end of ARRAY.
  913. ***************
  914. *** 559,569 ****
  915.   Takes extra time to study SCALAR ($_ if unspecified) in anticipation of
  916.   doing many pattern matches on the string before it is next modified.
  917.   This may or may not save time, depending on the nature and number of patterns
  918. ! you are searching on\*(--you probably want to compare runtimes with and
  919.   without it to see which runs faster.
  920.   Those loops which scan for many short constant strings (including the constant
  921.   parts of more complex patterns) will benefit most.
  922. ! For example, a loop which inserts index producing entries before an line
  923.   containing a certain pattern:
  924.   .nf
  925.   
  926. --- 565,583 ----
  927.   Takes extra time to study SCALAR ($_ if unspecified) in anticipation of
  928.   doing many pattern matches on the string before it is next modified.
  929.   This may or may not save time, depending on the nature and number of patterns
  930. ! you are searching on, and on the distribution of character frequencies in
  931. ! the string to be searched\*(--you probably want to compare runtimes with and
  932.   without it to see which runs faster.
  933.   Those loops which scan for many short constant strings (including the constant
  934.   parts of more complex patterns) will benefit most.
  935. ! (The way study works is this: a linked list of every character in the string
  936. ! to be searched is made, so we know, for example, where all the `k' characters
  937. ! are.
  938. ! From each search string, the rarest character is selected, based on some
  939. ! static frequency tables constructed from some C programs and English text.
  940. ! Only those places that contain this \*(L"rarest\*(R" character are examined.)
  941. ! .Sp
  942. ! For example, here is a loop which inserts index producing entries before an line
  943.   containing a certain pattern:
  944.   .nf
  945.   
  946. ***************
  947. *** 578,583 ****
  948. --- 592,628 ----
  949.       }
  950.   
  951.   .fi
  952. + In searching for /\ebfoo\eb/, only those locations in $_ that contain `f'
  953. + will be looked at, because `f' is rarer than `o'.
  954. + In general, this is a big win except in pathological cases.
  955. + The only question is whether it saves you more time than it took to build
  956. + the linked list in the first place.
  957. + .Sp
  958. + Note that if you have to look for strings that you don't know till runtime,
  959. + you can build an entire loop as a string and eval that to avoid recompiling
  960. + all your patterns all the time.
  961. + Together with setting $/ to input entire files as one record, this can
  962. + be very fast, often faster than specialized programs like fgrep.
  963. + The following scans a list of files (@files)
  964. + for a list of words (@words), and prints out the names of those files that
  965. + contain a match:
  966. + .nf
  967. + .ne 12
  968. +     $search = 'while (<>) { study;';
  969. +     foreach $word (@words) {
  970. +         $search .= "\e++$seen{\e$ARGV} if /\eb$word\eb/;\en";
  971. +     }
  972. +     $search .= "}";
  973. +     @ARGV = @files;
  974. +     $/ = "\e177";        # something that doesn't occur
  975. +     eval $search;        # this screams
  976. +     $/ = "\en";        # put back to normal input delim
  977. +     foreach $file (sort keys(seen)) {
  978. +         print $file,"\en";
  979. +     }
  980. + .fi
  981.   .Ip "substr(EXPR,OFFSET,LEN)" 8 2
  982.   Extracts a substring out of EXPR and returns it.
  983.   First character is at offset 0, or whatever you've set $[ to.
  984. ***************
  985. *** 639,644 ****
  986. --- 684,691 ----
  987.   
  988.       ($HOST = $host) =~ tr/a-z/A-Z/;
  989.   
  990. +     y/\e001-@[-_{-\e177/ /;    \h'|3i'# change non-alphas to space
  991.   .fi
  992.   .Ip "umask(EXPR)" 8 3
  993.   Sets the umask for the process and returns the old one.
  994. ***************
  995. *** 650,655 ****
  996. --- 697,703 ----
  997.   .ne 2
  998.       $cnt = unlink 'a','b','c';
  999.       unlink @goners;
  1000. +     unlink <*.bak>;
  1001.   
  1002.   .fi
  1003.   Note: unlink will not delete directories unless you are superuser and the \-U
  1004. ***************
  1005. *** 671,677 ****
  1006.   modification times, in that order.
  1007.   Returns the number of files successfully changed.
  1008.   The inode modification time of each file is set to the current time.
  1009. ! Example of a "touch" command:
  1010.   .nf
  1011.   
  1012.   .ne 3
  1013. --- 719,725 ----
  1014.   modification times, in that order.
  1015.   Returns the number of files successfully changed.
  1016.   The inode modification time of each file is set to the current time.
  1017. ! Example of a \*(L"touch\*(R" command:
  1018.   .nf
  1019.   
  1020.   .ne 3
  1021. ***************
  1022. *** 769,775 ****
  1023.   that is ($_[0], $_[1], .\|.\|.).
  1024.   The return value of the subroutine is the value of the last expression
  1025.   evaluated.
  1026. ! To create local variables see the "local" operator.
  1027.   .PP
  1028.   A subroutine is called using the
  1029.   .I do
  1030. --- 817,823 ----
  1031.   that is ($_[0], $_[1], .\|.\|.).
  1032.   The return value of the subroutine is the value of the last expression
  1033.   evaluated.
  1034. ! To create local variables see the \*(L"local\*(R" operator.
  1035.   .PP
  1036.   A subroutine is called using the
  1037.   .I do
  1038. ***************
  1039. *** 830,836 ****
  1040.   those supplied in the Version 8 regexp routines.
  1041.   (In fact, the routines are derived from Henry Spencer's freely redistributable
  1042.   reimplementation of the V8 routines.)
  1043. ! In addition, \ew matches an alphanumeric character (including "_") and \eW a nonalphanumeric.
  1044.   Word boundaries may be matched by \eb, and non-boundaries by \eB.
  1045.   A whitespace character is matched by \es, non-whitespace by \eS.
  1046.   A numeric character is matched by \ed, non-numeric by \eD.
  1047. --- 878,884 ----
  1048.   those supplied in the Version 8 regexp routines.
  1049.   (In fact, the routines are derived from Henry Spencer's freely redistributable
  1050.   reimplementation of the V8 routines.)
  1051. ! In addition, \ew matches an alphanumeric character (including \*(L"_\*(R") and \eW a nonalphanumeric.
  1052.   Word boundaries may be matched by \eb, and non-boundaries by \eB.
  1053.   A whitespace character is matched by \es, non-whitespace by \eS.
  1054.   A numeric character is matched by \ed, non-numeric by \eD.
  1055. ***************
  1056. *** 1011,1017 ****
  1057.   The following names have special meaning to
  1058.   .IR perl .
  1059.   I could have used alphabetic symbols for some of these, but I didn't want
  1060. ! to take the chance that someone would say reset "a-zA-Z" and wipe them all
  1061.   out.
  1062.   You'll just have to suffer along with these silly symbols.
  1063.   Most of them have reasonable mnemonics, or analogues in one of the shells.
  1064. --- 1059,1065 ----
  1065.   The following names have special meaning to
  1066.   .IR perl .
  1067.   I could have used alphabetic symbols for some of these, but I didn't want
  1068. ! to take the chance that someone would say reset \*(L"a-zA-Z\*(R" and wipe them all
  1069.   out.
  1070.   You'll just have to suffer along with these silly symbols.
  1071.   Most of them have reasonable mnemonics, or analogues in one of the shells.
  1072. ***************
  1073. *** 1167,1173 ****
  1074.   .Ip $@ 8 2
  1075.   The error message from the last eval command.
  1076.   If null, the last eval parsed and executed correctly.
  1077. ! (Mnemonic: Where was the syntax error "at"?)
  1078.   .Ip $< 8 2
  1079.   The real uid of this process.
  1080.   (Mnemonic: it's the uid you came FROM, if you're running setuid.)
  1081. --- 1215,1221 ----
  1082.   .Ip $@ 8 2
  1083.   The error message from the last eval command.
  1084.   If null, the last eval parsed and executed correctly.
  1085. ! (Mnemonic: Where was the syntax error \*(L"at\*(R"?)
  1086.   .Ip $< 8 2
  1087.   The real uid of this process.
  1088.   (Mnemonic: it's the uid you came FROM, if you're running setuid.)
  1089. ***************
  1090. *** 1206,1214 ****
  1091.   See $0 for the command name.
  1092.   .Ip @INC 8 3
  1093.   The array INC contains the list of places to look for perl scripts to be
  1094. ! evaluated by the "do EXPR" command.
  1095.   It initially consists of the arguments to any -I command line switches, followed
  1096. ! by the default perl library, probably "/usr/local/lib/perl".
  1097.   .Ip $ENV{expr} 8 2
  1098.   The associative array ENV contains your current environment.
  1099.   Setting a value in ENV changes the environment for child processes.
  1100. --- 1254,1262 ----
  1101.   See $0 for the command name.
  1102.   .Ip @INC 8 3
  1103.   The array INC contains the list of places to look for perl scripts to be
  1104. ! evaluated by the \*(L"do EXPR\*(R" command.
  1105.   It initially consists of the arguments to any -I command line switches, followed
  1106. ! by the default perl library, probably \*(L"/usr/local/lib/perl\*(R".
  1107.   .Ip $ENV{expr} 8 2
  1108.   The associative array ENV contains your current environment.
  1109.   Setting a value in ENV changes the environment for child processes.
  1110.  
  1111. Index: perly.c
  1112. Prereq: 2.0
  1113. *** perly.c.old    Tue Jun 28 16:40:49 1988
  1114. --- perly.c    Tue Jun 28 16:40:51 1988
  1115. ***************
  1116. *** 1,6 ****
  1117. ! char rcsid[] = "$Header: perly.c,v 2.0 88/06/05 00:09:56 root Exp $";
  1118.   /*
  1119.    * $Log:    perly.c,v $
  1120.    * Revision 2.0  88/06/05  00:09:56  root
  1121.    * Baseline version 2.0.
  1122.    * 
  1123. --- 1,9 ----
  1124. ! char rcsid[] = "$Header: perly.c,v 2.0.1.1 88/06/28 16:36:49 root Exp $";
  1125.   /*
  1126.    * $Log:    perly.c,v $
  1127. +  * Revision 2.0.1.1  88/06/28  16:36:49  root
  1128. +  * patch1: added DOSUID code
  1129. +  * 
  1130.    * Revision 2.0  88/06/05  00:09:56  root
  1131.    * Baseline version 2.0.
  1132.    * 
  1133. ***************
  1134. *** 26,31 ****
  1135. --- 29,38 ----
  1136.       register char *s;
  1137.       char *index(), *strcpy(), *getenv();
  1138.       bool dosearch = FALSE;
  1139. + #ifdef DOSUID
  1140. +     char **origargv = argv;
  1141. +     char *validarg = "";
  1142. + #endif
  1143.   
  1144.       uid = (int)getuid();
  1145.       euid = (int)geteuid();
  1146. ***************
  1147. *** 36,50 ****
  1148.       for (argc--,argv++; argc; argc--,argv++) {
  1149.       if (argv[0][0] != '-' || !argv[0][1])
  1150.           break;
  1151.         reswitch:
  1152. !     switch (argv[0][1]) {
  1153.       case 'a':
  1154.           minus_a = TRUE;
  1155. !         strcpy(argv[0], argv[0]+1);
  1156.           goto reswitch;
  1157.   #ifdef DEBUGGING
  1158.       case 'D':
  1159. !         debug = atoi(argv[0]+2);
  1160.   #ifdef YYDEBUG
  1161.           yydebug = (debug & 1);
  1162.   #endif
  1163. --- 43,64 ----
  1164.       for (argc--,argv++; argc; argc--,argv++) {
  1165.       if (argv[0][0] != '-' || !argv[0][1])
  1166.           break;
  1167. + #ifdef DOSUID
  1168. +     if (*validarg)
  1169. +     validarg = " PHOOEY ";
  1170. +     else
  1171. +     validarg = argv[0];
  1172. + #endif
  1173. +     s = argv[0]+1;
  1174.         reswitch:
  1175. !     switch (*s) {
  1176.       case 'a':
  1177.           minus_a = TRUE;
  1178. !         s++;
  1179.           goto reswitch;
  1180.   #ifdef DEBUGGING
  1181.       case 'D':
  1182. !         debug = atoi(s+1);
  1183.   #ifdef YYDEBUG
  1184.           yydebug = (debug & 1);
  1185.   #endif
  1186. ***************
  1187. *** 62,75 ****
  1188.           argc--,argv++;
  1189.           break;
  1190.       case 'i':
  1191. !         inplace = savestr(argv[0]+2);
  1192.           argvoutstab = stabent("ARGVOUT",TRUE);
  1193.           break;
  1194.       case 'I':
  1195. !         str_cat(str,argv[0]);
  1196.           str_cat(str," ");
  1197. !         if (argv[0][2]) {
  1198. !         apush(incstab->stab_array,str_make(argv[0]+2));
  1199.           }
  1200.           else {
  1201.           apush(incstab->stab_array,str_make(argv[1]));
  1202. --- 76,90 ----
  1203.           argc--,argv++;
  1204.           break;
  1205.       case 'i':
  1206. !         inplace = savestr(s+1);
  1207.           argvoutstab = stabent("ARGVOUT",TRUE);
  1208.           break;
  1209.       case 'I':
  1210. !         str_cat(str,"-");
  1211. !         str_cat(str,s);
  1212.           str_cat(str," ");
  1213. !         if (s[1]) {
  1214. !         apush(incstab->stab_array,str_make(s+1));
  1215.           }
  1216.           else {
  1217.           apush(incstab->stab_array,str_make(argv[1]));
  1218. ***************
  1219. *** 80,106 ****
  1220.           break;
  1221.       case 'n':
  1222.           minus_n = TRUE;
  1223. !         strcpy(argv[0], argv[0]+1);
  1224.           goto reswitch;
  1225.       case 'p':
  1226.           minus_p = TRUE;
  1227. !         strcpy(argv[0], argv[0]+1);
  1228.           goto reswitch;
  1229.       case 'P':
  1230.           preprocess = TRUE;
  1231. !         strcpy(argv[0], argv[0]+1);
  1232.           goto reswitch;
  1233.       case 's':
  1234.           doswitches = TRUE;
  1235. !         strcpy(argv[0], argv[0]+1);
  1236.           goto reswitch;
  1237.       case 'S':
  1238.           dosearch = TRUE;
  1239. !         strcpy(argv[0], argv[0]+1);
  1240.           goto reswitch;
  1241.       case 'U':
  1242.           unsafe = TRUE;
  1243. !         strcpy(argv[0], argv[0]+1);
  1244.           goto reswitch;
  1245.       case 'v':
  1246.           version();
  1247. --- 95,121 ----
  1248.           break;
  1249.       case 'n':
  1250.           minus_n = TRUE;
  1251. !         s++;
  1252.           goto reswitch;
  1253.       case 'p':
  1254.           minus_p = TRUE;
  1255. !         s++;
  1256.           goto reswitch;
  1257.       case 'P':
  1258.           preprocess = TRUE;
  1259. !         s++;
  1260.           goto reswitch;
  1261.       case 's':
  1262.           doswitches = TRUE;
  1263. !         s++;
  1264.           goto reswitch;
  1265.       case 'S':
  1266.           dosearch = TRUE;
  1267. !         s++;
  1268.           goto reswitch;
  1269.       case 'U':
  1270.           unsafe = TRUE;
  1271. !         s++;
  1272.           goto reswitch;
  1273.       case 'v':
  1274.           version();
  1275. ***************
  1276. *** 107,113 ****
  1277.           exit(0);
  1278.       case 'w':
  1279.           dowarn = TRUE;
  1280. !         strcpy(argv[0], argv[0]+1);
  1281.           goto reswitch;
  1282.       case '-':
  1283.           argc--,argv++;
  1284. --- 122,128 ----
  1285.           exit(0);
  1286.       case 'w':
  1287.           dowarn = TRUE;
  1288. !         s++;
  1289.           goto reswitch;
  1290.       case '-':
  1291.           argc--,argv++;
  1292. ***************
  1293. *** 115,121 ****
  1294.       case 0:
  1295.           break;
  1296.       default:
  1297. !         fatal("Unrecognized switch: %s",argv[0]);
  1298.       }
  1299.       }
  1300.     switch_end:
  1301. --- 130,136 ----
  1302.       case 0:
  1303.           break;
  1304.       default:
  1305. !         fatal("Unrecognized switch: -%s",s);
  1306.       }
  1307.       }
  1308.     switch_end:
  1309. ***************
  1310. *** 186,191 ****
  1311. --- 201,210 ----
  1312.    -e 's/^#.*//' \
  1313.    %s | %s -C %s %s",
  1314.         argv[0], CPPSTDIN, str_get(str), CPPMINUS);
  1315. + #ifdef IAMSUID
  1316. +     if (euid != uid && !euid)    /* if running suidperl */
  1317. +         seteuid(uid);        /* musn't stay setuid root */
  1318. + #endif
  1319.       rsfp = popen(buf,"r");
  1320.       }
  1321.       else if (!*argv[0])
  1322. ***************
  1323. *** 192,200 ****
  1324.       rsfp = stdin;
  1325.       else
  1326.       rsfp = fopen(argv[0],"r");
  1327. !     if (rsfp == Nullfp)
  1328.       fatal("Perl script \"%s\" doesn't seem to exist",filename);
  1329.       str_free(str);        /* free -I directories */
  1330.   
  1331.       defstab = stabent("_",TRUE);
  1332.   
  1333. --- 211,302 ----
  1334.       rsfp = stdin;
  1335.       else
  1336.       rsfp = fopen(argv[0],"r");
  1337. !     if (rsfp == Nullfp) {
  1338. ! #ifdef DOSUID
  1339. ! #ifndef IAMSUID
  1340. !     if (euid && stat(filename,&statbuf) >= 0 &&
  1341. !       statbuf.st_mode & (S_ISUID|S_ISGID)) {
  1342. !         execvp("suidperl", origargv);    /* try again */
  1343. !         fatal("Can't do setuid\n");
  1344. !     }
  1345. ! #endif
  1346. ! #endif
  1347.       fatal("Perl script \"%s\" doesn't seem to exist",filename);
  1348. +     }
  1349.       str_free(str);        /* free -I directories */
  1350. +     /* do we need to emulate setuid on scripts? */
  1351. +     /* This code is for those BSD systems that have setuid #! scripts disabled
  1352. +      * in the kernel because of a security problem.  Merely defining DOSUID
  1353. +      * in perl will not fix that problem, but if you have disabled setuid
  1354. +      * scripts in the kernel, this will attempt to emulate setuid and setgid
  1355. +      * on scripts that have those now-otherwise-useless bits set.  The setuid
  1356. +      * root version must be called suidperl.  If regular perl discovers that
  1357. +      * it has opened a setuid script, it calls suidperl with the same argv
  1358. +      * that it had.  If suidperl finds that the script it has just opened
  1359. +      * is NOT setuid root, it sets the effective uid back to the uid.  We
  1360. +      * don't just make perl setuid root because that loses the effective
  1361. +      * uid we had before invoking perl, if it was different from the uid.
  1362. +      *
  1363. +      * DOSUID must be defined in both perl and suidperl, and IAMSUID must
  1364. +      * be defined in suidperl only.  suidperl must be setuid root.  The
  1365. +      * Configure script will set this up for you if you want it.
  1366. +      */
  1367. + #ifdef DOSUID
  1368. +     if (fstat(fileno(rsfp),&statbuf) < 0)    /* normal stat is insecure */
  1369. +     fatal("Can't stat script \"%s\"",filename);
  1370. +     if (statbuf.st_mode & (S_ISUID|S_ISGID)) {
  1371. +     int len;
  1372. +     if (access(filename,1))        /* as a double check */
  1373. +         fatal("Permission denied");
  1374. +     if ((statbuf.st_mode & S_IFMT) != S_IFREG)
  1375. +         fatal("Permission denied");
  1376. +     doswitches = FALSE;        /* -s is insecure in suid */
  1377. +     line++;
  1378. +     if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
  1379. +       strnNE(tokenbuf,"#!",2) )    /* required even on Sys V */
  1380. +         fatal("No #! line");
  1381. +     for (s = tokenbuf+2; !isspace(*s); s++) ;
  1382. +     if (strnNE(s-4,"perl",4))    /* sanity check */
  1383. +         fatal("Not a perl script");
  1384. +     while (*s && isspace(*s)) s++;
  1385. +     /*
  1386. +      * #! arg must be what we saw above.  They can invoke it by
  1387. +      * mentioning suidperl explicitly, but they may not add any strange
  1388. +      * arguments beyond what #! says if they do invoke suidperl that way.
  1389. +      */
  1390. +     len = strlen(validarg);
  1391. +     if (strEQ(validarg," PHOOEY ") ||
  1392. +         strnNE(s,validarg,len) || !isspace(s[len]))
  1393. +         fatal("Arg must be \"%s\"\n",s);
  1394. +     if (euid) {    /* oops, we're not the setuid root perl */
  1395. +         fclose(rsfp);
  1396. + #ifndef IAMSUID
  1397. +         execvp("suidperl", origargv);    /* try again */
  1398. + #endif
  1399. +         fatal("Can't do setuid\n");
  1400. +     }
  1401. +     if (statbuf.st_mode & S_ISUID && statbuf.st_uid != euid)
  1402. +         seteuid(statbuf.st_uid);    /* all that for this */
  1403. +     else if (uid)            /* oops, mustn't run as root */
  1404. +         seteuid(uid);
  1405. +     if (statbuf.st_mode & S_ISGID && statbuf.st_gid != getegid())
  1406. +         setegid(statbuf.st_gid);
  1407. +     euid = (int)geteuid();
  1408. +     if (!cando(S_IEXEC,TRUE))
  1409. +         fatal("Permission denied\n");    /* they can't do this */
  1410. +     }
  1411. + #ifdef IAMSUID
  1412. +     else if (preprocess)
  1413. +     fatal("-P not allowed for setuid/setgid script\n");
  1414. +     else
  1415. +     fatal("Script is not setuid/setgid in suidperl\n");
  1416. + #endif /* IAMSUID */
  1417. + #endif /* DOSUID */
  1418.   
  1419.       defstab = stabent("_",TRUE);
  1420.   
  1421.  
  1422. Index: regexp.c
  1423. Prereq: 2.0
  1424. *** regexp.c.old    Tue Jun 28 16:41:00 1988
  1425. --- regexp.c    Tue Jun 28 16:41:02 1988
  1426. ***************
  1427. *** 7,15 ****
  1428.    * blame Henry for some of the lack of readability.
  1429.    */
  1430.   
  1431. ! /* $Header: regexp.c,v 2.0 88/06/05 00:10:45 root Exp $
  1432.    *
  1433.    * $Log:    regexp.c,v $
  1434.    * Revision 2.0  88/06/05  00:10:45  root
  1435.    * Baseline version 2.0.
  1436.    * 
  1437. --- 7,18 ----
  1438.    * blame Henry for some of the lack of readability.
  1439.    */
  1440.   
  1441. ! /* $Header: regexp.c,v 2.0.1.1 88/06/28 16:37:19 root Exp $
  1442.    *
  1443.    * $Log:    regexp.c,v $
  1444. +  * Revision 2.0.1.1  88/06/28  16:37:19  root
  1445. +  * patch1: removed redundant debugging code
  1446. +  * 
  1447.    * Revision 2.0  88/06/05  00:10:45  root
  1448.    * Baseline version 2.0.
  1449.    * 
  1450. ***************
  1451. *** 398,408 ****
  1452.               if (len > !(sawstudy))
  1453.                   fbmcompile(r->regmust);
  1454.               *(long*)&r->regmust->str_nval = 100;
  1455. - #ifdef DEBUGGING
  1456. -             if (debug & 512)
  1457. -                 fprintf(stderr,"must = '%s' back=%d\n",
  1458. -                 longest,back);
  1459. - #endif
  1460.           }
  1461.           else
  1462.               str_free(longest);
  1463. --- 401,406 ----
  1464.  
  1465. Index: str.c
  1466. Prereq: 2.0
  1467. *** str.c.old    Tue Jun 28 16:41:09 1988
  1468. --- str.c    Tue Jun 28 16:41:10 1988
  1469. ***************
  1470. *** 1,6 ****
  1471. ! /* $Header: str.c,v 2.0 88/06/05 00:11:07 root Exp $
  1472.    *
  1473.    * $Log:    str.c,v $
  1474.    * Revision 2.0  88/06/05  00:11:07  root
  1475.    * Baseline version 2.0.
  1476.    * 
  1477. --- 1,9 ----
  1478. ! /* $Header: str.c,v 2.0.1.1 88/06/28 16:38:11 root Exp $
  1479.    *
  1480.    * $Log:    str.c,v $
  1481. +  * Revision 2.0.1.1  88/06/28  16:38:11  root
  1482. +  * patch1: autoincrement of '' didn't work right.
  1483. +  * 
  1484.    * Revision 2.0  88/06/05  00:11:07  root
  1485.    * Baseline version 2.0.
  1486.    * 
  1487. ***************
  1488. *** 468,473 ****
  1489. --- 471,477 ----
  1490.       if (!str->str_pok || !*str->str_ptr) {
  1491.       str->str_nval = 1.0;
  1492.       str->str_nok = 1;
  1493. +     str->str_pok = 0;
  1494.       return;
  1495.       }
  1496.       d = str->str_ptr;
  1497.  
  1498. Index: toke.c
  1499. Prereq: 2.0
  1500. *** toke.c.old    Tue Jun 28 16:41:16 1988
  1501. --- toke.c    Tue Jun 28 16:41:18 1988
  1502. ***************
  1503. *** 1,6 ****
  1504. ! /* $Header: toke.c,v 2.0 88/06/05 00:11:16 root Exp $
  1505.    *
  1506.    * $Log:    toke.c,v $
  1507.    * Revision 2.0  88/06/05  00:11:16  root
  1508.    * Baseline version 2.0.
  1509.    * 
  1510. --- 1,9 ----
  1511. ! /* $Header: toke.c,v 2.0.1.1 88/06/28 16:39:50 root Exp $
  1512.    *
  1513.    * $Log:    toke.c,v $
  1514. +  * Revision 2.0.1.1  88/06/28  16:39:50  root
  1515. +  * patch1: tr/x/y/ can dump core if y is shorter than x
  1516. +  * 
  1517.    * Revision 2.0  88/06/05  00:11:16  root
  1518.    * Baseline version 2.0.
  1519.    * 
  1520. ***************
  1521. *** 922,927 ****
  1522. --- 925,931 ----
  1523.       register char *r;
  1524.       register char *tbl = safemalloc(256);
  1525.       register int i;
  1526. +     register int j;
  1527.   
  1528.       arg[2].arg_type = A_NULL;
  1529.       arg[2].arg_ptr.arg_cval = tbl;
  1530. ***************
  1531. *** 942,951 ****
  1532.       safefree(r);
  1533.       r = t;
  1534.       }
  1535. !     for (i = 0; t[i]; i++) {
  1536. !     if (!r[i])
  1537. !         r[i] = r[i-1];
  1538. !     tbl[t[i] & 0377] = r[i];
  1539.       }
  1540.       if (r != t)
  1541.       safefree(r);
  1542. --- 946,955 ----
  1543.       safefree(r);
  1544.       r = t;
  1545.       }
  1546. !     for (i = 0, j = 0; t[i]; i++,j++) {
  1547. !     if (!r[j])
  1548. !         --j;
  1549. !     tbl[t[i] & 0377] = r[j];
  1550.       }
  1551.       if (r != t)
  1552.       safefree(r);
  1553.  
  1554.