home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sources / misc / 3803 next >
Encoding:
Text File  |  1992-08-14  |  49.6 KB  |  2,130 lines

  1. Newsgroups: comp.sources.misc
  2. Path: sparky!kent
  3. From: sjg@zen.void.oz.au (Simon J. Gerraty)
  4. Subject:  v31i074:  pdksh - Public Domain Korn Shell, Patch06a/2
  5. Message-ID: <csm-v31i074=pdksh.093459@sparky.IMD.Sterling.COM>
  6. Followup-To: comp.sources.d
  7. X-Md4-Signature: b99a1dcb6cb0d5a1262775c4d240a60f
  8. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  9. Organization: Sterling Software
  10. Date: Fri, 14 Aug 1992 14:41:48 GMT
  11. Approved: kent@sparky.imd.sterling.com
  12. Lines: 2116
  13.  
  14. Submitted-by: sjg@zen.void.oz.au (Simon J. Gerraty)
  15. Posting-number: Volume 31, Issue 74
  16. Archive-name: pdksh/patch06a
  17. Environment: UNIX
  18. Patch-To: pdksh: Volume 25, Issue 47-55
  19.  
  20. This is patch06 (a two part patch). Please apply both parts to complete
  21. the patch.
  22.  
  23. This patch fixes a bug in the handling of re-directed loops.  It adds 
  24. "special" support for variables FCEDIT and COLUMNS.
  25.  
  26. It also incorporates a significant contribution from Peter Collinson 
  27. of Hillside Systems/BSDI
  28.  
  29. I've guessed at the flags in Makefile and sh/Makefile, but you should 
  30. not have much trouble building this on either BSDI's BSD/386 or Bill 
  31. and Lyne Jolitz's 386bsd. 
  32.  
  33. See ChangeLog for other details.
  34.  
  35. Apply this patch by changing directory to the root of the source tree 
  36. and using the command:
  37.  
  38.     patch -p0 < this_file
  39.  
  40. The following is a complete list of patches to date.
  41.  
  42. Prereq: 09-Nov-91
  43. Prereq: 10-Nov-91
  44. Prereq: 25-Nov-91
  45. Prereq: 25-Apr-92
  46. Prereq: 26-Apr-92
  47. Prereq: 27-Apr-92
  48. Prereq: 12-May-92
  49. *** PATCHDATES.old    Tue May 12 13:42:00 1992
  50. --- PATCHDATES    Mon Aug 10 21:59:12 1992
  51. ***************
  52. *** 6,8 ****
  53. --- 6,9 ----
  54.   26-Apr-92
  55.   27-Apr-92
  56.   12-May-92
  57. + 02-Aug-92
  58. *** ChangeLog.old    Tue May 12 13:42:00 1992
  59. --- ChangeLog    Mon Aug 10 21:59:03 1992
  60. ***************
  61. *** 1,3 ****
  62. --- 1,12 ----
  63. + Sat Aug  1 17:11:24 1992  Simon J. Gerraty  (sjg@zen)
  64. +     * Incorporated massive contribution from Peter Collinson
  65. +     Refer to Changes.pc
  66. +     * Incorporated Emacs-style completion provided by
  67. +     Neil.Smithline@eng.sun.com this a bit nicer than the standard ksh
  68. +     file completion.
  69.   Sun May  3 17:50:03 1992  Simon J. Gerraty  (sjg@zen)
  70.   
  71.       * Updated MACHINES.
  72. *** /dev/null    Mon Aug 10 22:06:03 1992
  73. --- Changes.pc    Mon Aug 10 22:06:01 1992
  74. ***************
  75. *** 0 ****
  76. --- 1,28 ----
  77. + Changes by Peter Collinson - Hillside Systems/BSDI - July 1992
  78. + a)    Add select command - this cannot be ksh without that.
  79. +     (It NEEDS typedefs too)
  80. + b)    Remove all the bcopys from vi.c
  81. +     add 
  82. +     #define memmove in sh.h for BSD systems
  83. + c)    Add <Esc>* command to vi mode - expands to a list of files
  84. +     using the menu printing routine
  85. + d)    Add my version of history, that works much like the `proper' ksh
  86. +     storing data in a file that is shared between different invocations
  87. +     of the shell.
  88. + e)    Add the ability to redirect to am expansion... ie
  89. +         ls > o*
  90. +     if o* is unique then it puts it into the file that matches
  91. +     otherwise it puts it to a file called o*... this is current
  92. +     behaviour.
  93. + f)    Add alternations, from Csh.d) This is not part of ksh but is something
  94. +     that csh users really miss from the Bourne shell derivatives. The idea
  95. +     is that lists inside curly braces expand to arguments. ie.
  96. +         exampl{a,b,c,d,e}
  97. +     will expand to 5 arguments
  98. +         exampla examplb examplc exampld example
  99. +     Recursive lists are permitted.
  100. + g)    Add suspend as a built-in alias.
  101. + h)    Port to BSD/386 - add _POSIX_TERM and _BSDI as defines.
  102. *** MACHINES.old    Tue May 12 13:42:00 1992
  103. --- MACHINES    Mon Aug 10 21:59:08 1992
  104. ***************
  105. *** 20,26 ****
  106.   sun3,    SunOS 4.1.1        1,4    {cc,gcc} -ansi -D_BSD -DHAVE_SYS_STDTYPES
  107.   Bull DPX/2, B.O.S. 2.00.45    1,5    {cc,gcc-2.1} -ansi -D_POSIX_SOURCE
  108.   Bull XPS-100            1,6    cc -D_SYSV -DUSE_SIGNAL
  109.   
  110.   NOTES:
  111.   The table above sumarizes the config used.  {cc,gcc} indicates
  112. --- 20,26 ----
  113.   sun3,    SunOS 4.1.1        1,4    {cc,gcc} -ansi -D_BSD -DHAVE_SYS_STDTYPES
  114.   Bull DPX/2, B.O.S. 2.00.45    1,5    {cc,gcc-2.1} -ansi -D_POSIX_SOURCE
  115.   Bull XPS-100            1,6    cc -D_SYSV -DUSE_SIGNAL
  116. ! i386,    BSDI BSD/386        2
  117.   
  118.   NOTES:
  119.   The table above sumarizes the config used.  {cc,gcc} indicates
  120. *** MANIFEST.old    Tue May 12 13:42:00 1992
  121. --- MANIFEST    Mon Aug 10 22:06:04 1992
  122. ***************
  123. *** 2,7 ****
  124. --- 2,8 ----
  125.   -----------------------------------------------------------
  126.    ChangeLog                 1    Current change history
  127.    Changes.jrm               1    
  128. +  Changes.pc                1    
  129.    Changes.mlj               1    
  130.    INSTALL                   1    Installation notes
  131.    MACHINES                  1    Systems the shell has been built on
  132. *** Makefile.old    Tue May 12 13:42:00 1992
  133. --- Makefile    Mon Aug 10 21:59:10 1992
  134. ***************
  135. *** 1,5 ****
  136.   # PD Bourne/Korn Shell
  137. ! # $Id: Makefile,v 1.2 1992/04/25 08:17:25 sjg Exp $
  138.   
  139.   SHELL = /bin/sh
  140.   MAKE  = make
  141. --- 1,5 ----
  142.   # PD Bourne/Korn Shell
  143. ! # $Id: Makefile,v 1.3 1992/08/10 11:59:10 sjg Exp $
  144.   
  145.   SHELL = /bin/sh
  146.   MAKE  = make
  147. ***************
  148. *** 10,17 ****
  149.   CONFIG= -D_BSD 
  150.   #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
  151.   #CONFIG= -D_V7
  152. ! #CONFIG= -D_ST        /* Atari ST */
  153.   MANPAGES = ksh.1
  154.   #MANDIR=/usr/catman/u_man/man1
  155.   #MANDIR=/usr/man/man1
  156. --- 10,17 ----
  157.   CONFIG= -D_BSD 
  158.   #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
  159.   #CONFIG= -D_V7
  160. ! #CONFIG= -D_ST                # Atari ST
  161. ! #CONFIG= -D_BSDI -D_POSIX_TERM        # BSD/386
  162.   MANPAGES = ksh.1
  163.   #MANDIR=/usr/catman/u_man/man1
  164.   #MANDIR=/usr/man/man1
  165. *** etc/ksh.kshrc.old    Tue May 12 13:42:00 1992
  166. --- etc/ksh.kshrc    Mon Aug 10 22:00:08 1992
  167. ***************
  168. *** 15,22 ****
  169.   # SEE ALSO:
  170.   #    $HOME/.kshrc
  171.   #
  172.   # RCSid:
  173. ! #    $Id: ksh.kshrc,v 1.2 1992/04/27 07:09:28 sjg Exp $
  174.   #    @(#)Copyright (c) 1991 Simon J. Gerraty
  175.   #
  176.   #    This file is provided in the hope that it will
  177. --- 15,24 ----
  178.   # SEE ALSO:
  179.   #    $HOME/.kshrc
  180.   #
  181.   # RCSid:
  182. ! #    $Id: ksh.kshrc,v 1.3 1992/08/10 12:00:08 sjg Exp $
  183. ! #
  184.   #    @(#)Copyright (c) 1991 Simon J. Gerraty
  185.   #
  186.   #    This file is provided in the hope that it will
  187. ***************
  188. *** 40,52 ****
  189.       tty=`tty`
  190.       tty=`basename $tty`
  191.   
  192. !     set -o ${FCEDIT:-$EDITOR}
  193.   
  194.       # the PD ksh is not 100% compatible
  195.       case "$KSH_VERSION" in
  196.       *PD*)    # PD ksh
  197. !             bind ^?=delete-char-backward
  198. !             bind ^[^?=delete-word-backward
  199.           ;;
  200.       *)    # real ksh ?
  201.           ;;
  202. --- 42,64 ----
  203.       tty=`tty`
  204.       tty=`basename $tty`
  205.   
  206. !     set -o $EDITOR
  207.   
  208. +     alias ls='ls -CF'
  209. +     alias h='fc -l | more'
  210.       # the PD ksh is not 100% compatible
  211.       case "$KSH_VERSION" in
  212.       *PD*)    # PD ksh
  213. !         case "$TERM" in
  214. !         xterm*)
  215. !             # bind arrow keys
  216. !             bind '^[['=prefix-2
  217. !             bind '^XA'=up-history
  218. !             bind '^XB'=down-history
  219. !             bind '^XC'=forward-char
  220. !             bind '^XD'=backward-char
  221. !             ;;
  222. !         esac
  223.           ;;
  224.       *)    # real ksh ?
  225.           ;;
  226. ***************
  227. *** 53,60 ****
  228. --- 65,75 ----
  229.       esac
  230.       case "$TERM" in
  231.       sun*)
  232. +         # these are not as neat as their csh equivalents
  233.           if [ "$tty" != console ]; then
  234. +             # ilabel
  235.               ILS='\033]L'; ILE='\033\\'
  236. +             # window title bar
  237.               WLS='\033]l'; WLE='\033\\'
  238.           fi
  239.           ;;
  240. ***************
  241. *** 66,72 ****
  242.       esac
  243.       # do we want window decorations?
  244.       if [ "$ILS" ]; then
  245. !         wftp () { ilabel "ftp $*"; "ftp" $*; ilabel "$USER@$HOSTNAME"; }
  246.           wcd () { "cd" $*; eval stripe; }
  247.           ilabel () { print -n "${ILS}$*${ILE}"; }
  248.           label () { print -n "${WLS}$*${WLE}"; }
  249. --- 81,88 ----
  250.       esac
  251.       # do we want window decorations?
  252.       if [ "$ILS" ]; then
  253. !         wftp () { ilabel "ftp $*"; "ftp" $*; 
  254. !             ilabel "$USER@$HOSTNAME"; }
  255.           wcd () { "cd" $*; eval stripe; }
  256.           ilabel () { print -n "${ILS}$*${ILE}"; }
  257.           label () { print -n "${WLS}$*${WLE}"; }
  258. ***************
  259. *** 77,84 ****
  260.           eval ilabel "$USER@$HOSTNAME"
  261.           PS1=$PROMPT
  262.       fi
  263. -     alias ls='ls -CF'
  264. -     alias h='fc -l | more'
  265.       alias quit=exit
  266.       alias cls=clear
  267.       alias logout=exit
  268. --- 93,98 ----
  269. *** etc/profile.old    Tue May 12 13:42:00 1992
  270. --- etc/profile    Mon Aug 10 22:00:11 1992
  271. ***************
  272. *** 5,18 ****
  273.   # DESCRIPTION:
  274.   #    This file is processed during login by /bin/sh
  275.   #    and /bin/ksh.  It is used to setup the default user
  276. ! #    environment.  It is processed with root privs.
  277.   #
  278.   # SEE ALSO:
  279.   #    $HOME/.profile
  280.   #    /etc/ksh.kshrc
  281. ! #
  282.   # RCSid:
  283. ! #    $Id: profile,v 1.3 1992/05/03 08:28:27 sjg Exp $
  284.   #    @(#)Copyright (c) 1991 Simon J. Gerraty
  285.   #
  286.   #    This file is provided in the hope that it will
  287. --- 5,19 ----
  288.   # DESCRIPTION:
  289.   #    This file is processed during login by /bin/sh
  290.   #    and /bin/ksh.  It is used to setup the default user
  291. ! #    environment.
  292.   #
  293.   # SEE ALSO:
  294.   #    $HOME/.profile
  295.   #    /etc/ksh.kshrc
  296.   # RCSid:
  297. ! #    $Id: profile,v 1.4 1992/08/10 12:00:11 sjg Exp $
  298. ! #
  299.   #    @(#)Copyright (c) 1991 Simon J. Gerraty
  300.   #
  301.   #    This file is provided in the hope that it will
  302. ***************
  303. *** 27,36 ****
  304.   *)    # do these once
  305.       _INIT_="$_INIT_"env
  306.       export _INIT_
  307. !     # sys_config.sh should set ARCH,OS,C,N,HOSTNAME,uname
  308. !     # we use these in lots of scripts...
  309. !     [ -f /etc/sys_config.sh ] && . /etc/sys_config.sh
  310.   
  311.       # pick one of the following for the default umask
  312.       # umask 002    # relaxed    -rwxrwxr-x
  313.       umask 022    # cautious    -rwxr-xr-x
  314. --- 28,56 ----
  315.   *)    # do these once
  316.       _INIT_="$_INIT_"env
  317.       export _INIT_
  318. !     case `echo -n ""` in
  319. !     -n*)
  320. !       _N_=""; _C_="\c";;
  321. !     *)
  322. !       _N_="-n"; _C_="";;
  323. !     esac
  324.   
  325. +     if [ -f /unix ]; then
  326. +           # System V
  327. +       [ -z "$TZ" -a -f /etc/TIMEZONE ] && . /etc/TIMEZONE
  328. +         set -- `who -r`
  329. +           case "$3" in
  330. +           S|5|0)    SINGLE=y;;
  331. +           *)    SINGLE=n;;
  332. +       esac
  333. +         # sys_config.sh should set ARCH,OS,C,N,HOSTNAME,uname
  334. +           # we use these in lots of scripts...
  335. +             [ "$SINGLE" = n -a -f /etc/sys_config.sh ] && . /etc/sys_config.sh
  336. +         else
  337. +           [ -f /etc/sys_config.sh ] && . /etc/sys_config.sh
  338. +           SINGLE=n        # doesn't matter so much
  339. +     fi
  340.       # pick one of the following for the default umask
  341.       # umask 002    # relaxed    -rwxrwxr-x
  342.       umask 022    # cautious    -rwxr-xr-x
  343. ***************
  344. *** 53,69 ****
  345.       case $OS in
  346.       SunOS)
  347.           # On sun's /bin -> /usr/bin so leave it out!
  348. !         PATH=.:/usr/bin:/usr/ucb:/usr/5bin
  349.           MANPATH=/usr/man
  350.           defterm=vt220
  351.           ;;
  352.       SCO-UNIX)
  353. !         PATH=.:/bin:/usr/bin:/usr/lbin:/usr/dbin:/usr/ldbin
  354.           MANPATH=/usr/man
  355.           defterm=ansi
  356.           ;;
  357.       B.O.S.)
  358. !         PATH=.:/bin:/usr/bin
  359.           if [ -d /usr/ucb ]; then
  360.               PATH=$PATH:/usr/ucb
  361.           fi
  362. --- 73,89 ----
  363.       case $OS in
  364.       SunOS)
  365.           # On sun's /bin -> /usr/bin so leave it out!
  366. !         PATH=/usr/bin:/usr/ucb:/usr/5bin:.
  367.           MANPATH=/usr/man
  368.           defterm=vt220
  369.           ;;
  370.       SCO-UNIX)
  371. !         PATH=/bin:/usr/bin:/usr/lbin:/usr/dbin:/usr/ldbin:.
  372.           MANPATH=/usr/man
  373.           defterm=ansi
  374.           ;;
  375.       B.O.S.)
  376. !         PATH=/bin:/usr/bin:.
  377.           if [ -d /usr/ucb ]; then
  378.               PATH=$PATH:/usr/ucb
  379.           fi
  380. ***************
  381. *** 73,79 ****
  382.           export SRC_COMPAT
  383.           ;;
  384.       *)
  385. !         PATH=.:/bin:/usr/bin
  386.           if [ -d /usr/ucb ]; then
  387.               PATH=$PATH:/usr/ucb
  388.           fi
  389. --- 93,99 ----
  390.           export SRC_COMPAT
  391.           ;;
  392.       *)
  393. !         PATH=/bin:/usr/bin:.
  394.           if [ -d /usr/ucb ]; then
  395.               PATH=$PATH:/usr/ucb
  396.           fi
  397. ***************
  398. *** 84,92 ****
  399.       if [ -d ${LOCAL}/bin ]; then
  400.           PATH=$PATH:${LOCAL}/bin
  401.       fi
  402. !     if [ -d $HOME/bin -a "$HOME" != / ]; then
  403. !         PATH=$PATH:$HOME/bin
  404. !     fi
  405.       if [ -d ${LOCAL}/man ]; then
  406.           MANPATH=$MANPATH:${LOCAL}/man
  407.       fi
  408. --- 104,121 ----
  409.       if [ -d ${LOCAL}/bin ]; then
  410.           PATH=$PATH:${LOCAL}/bin
  411.       fi
  412. !     case "$HOME" in
  413. !     /)    ;;
  414. !     ""|/tmp)
  415. !         echo "Using /tmp for HOME"
  416. !         HOME=/tmp; export HOME
  417. !         ;;
  418. !     *)
  419. !         if [ -d $HOME/bin ]; then
  420. !             PATH=$PATH:$HOME/bin
  421. !         fi
  422. !         ;;
  423. !     esac
  424.       if [ -d ${LOCAL}/man ]; then
  425.           MANPATH=$MANPATH:${LOCAL}/man
  426.       fi
  427. ***************
  428. *** 94,100 ****
  429.       LOGNAME=${LOGNAME:-`logname`}
  430.       USER=${USER:-$LOGNAME}
  431.   
  432. -     # this is adapted from my whoami.sh
  433.       # we expect id to produce output like:
  434.       # uid=100(sjg) gid=10(staff) groups=10(staff),...
  435.       S='('
  436. --- 123,128 ----
  437. ***************
  438. *** 101,107 ****
  439.       E=')'
  440.       GROUP=`id | cut -d= -f3 | \
  441.           sed -e "s;^[^${S}][^${S}]*${S}\([^${E}][^${E}]*\)${E}.*$;\1;"`
  442.       # set some group specific defaults
  443.       case "$GROUP" in
  444.       staff)    # staff deal with things that non-staff 
  445. --- 129,136 ----
  446.       E=')'
  447.       GROUP=`id | cut -d= -f3 | \
  448.           sed -e "s;^[^${S}][^${S}]*${S}\([^${E}][^${E}]*\)${E}.*$;\1;"`
  449. !     UID=`id | cut -d= -f2 | \
  450. !                 sed -e "s;\([^${S}]*\)${S}.*;\1;"`
  451.       # set some group specific defaults
  452.       case "$GROUP" in
  453.       staff)    # staff deal with things that non-staff 
  454. ***************
  455. *** 120,125 ****
  456. --- 149,155 ----
  457.       export LOCAL TTY PATH LOGNAME USER
  458.   
  459.       if [ -t 1 ]; then
  460. +         # we are interactive
  461.           TTY=`tty`
  462.           TTY=`basename $TTY`
  463.           ORGANIZATION=""
  464. ***************
  465. *** 133,144 ****
  466.           PAGER=${PAGER:-more}
  467.           export MAIL EMACSDIR MANPATH MAILPATH PAGER
  468.   
  469.           EDITOR=emacs
  470. !         FCEDIT=${EDITOR}    
  471. !         PROMPT="<$LOGNAME@$HOSTNAME>$ "
  472. !         PUBDIR=/usr/spool/uucppublic
  473. !         export PUBDIR 
  474.           [ -f /etc/profile.TeX ] && . /etc/profile.TeX
  475.       else
  476.           TTY=none
  477. --- 163,181 ----
  478.           PAGER=${PAGER:-more}
  479.           export MAIL EMACSDIR MANPATH MAILPATH PAGER
  480.   
  481. +         CVSROOT=${LOCAL}/src/master
  482.           EDITOR=emacs
  483. !         FCEDIT=$EDITOR
  484. !         export CVSROOT FCEDIT EDITOR
  485. ! #        EMACSLOADPATH=$EMACSDIR/lisp
  486. ! #        [ -d $LOCAL/lib/lisp ] && EMACSLOADPATH=$LOCAL/lib/lisp:$EMACSLOADPATH
  487. ! #        [ -d $HOME/lisp ] && EMACSLOADPATH=$HOME/lisp:$EMACSLOADPATH
  488. !         case $UID in 
  489. !         0)    PROMPT="<$LOGNAME@$HOSTNAME># ";;
  490. !         *)    PROMPT="<$LOGNAME@$HOSTNAME>$ ";;
  491. !         esac
  492. ! #        PUBDIR=/usr/spool/uucppublic
  493. ! #        export PUBDIR EMACSLOADPATH
  494.           [ -f /etc/profile.TeX ] && . /etc/profile.TeX
  495.       else
  496.           TTY=none
  497. ***************
  498. *** 149,155 ****
  499.           # we are Korn shell
  500.           SHELL=/bin/ksh
  501.           ENV=${HOME%/}/.kshrc
  502. !         PROMPT="<$LOGNAME@$HOSTNAME:!>$ "
  503.           export HISTSIZE HISTFILE ENV
  504.           CDPATH=.:$HOME
  505.           if [ "$TMOUT" ]; then
  506. --- 186,197 ----
  507.           # we are Korn shell
  508.           SHELL=/bin/ksh
  509.           ENV=${HOME%/}/.kshrc
  510. !         HISTFILE=${HOME%/}/.ksh_hist
  511. !         case $UID in
  512. !         0)
  513. !             PROMPT="<$LOGNAME@$HOSTNAME:!># ";;
  514. !         *)    PROMPT="<$LOGNAME@$HOSTNAME:!>$ ";;
  515. !         esac
  516.           export HISTSIZE HISTFILE ENV
  517.           CDPATH=.:$HOME
  518.           if [ "$TMOUT" ]; then
  519. ***************
  520. *** 159,166 ****
  521.           SHELL=/bin/sh
  522.       fi
  523.       PS1=$PROMPT
  524. !     export SHELL PS1 EDITOR PATH PROMPT HOSTNAME CDPATH FCEDIT
  525.   ;;
  526.   esac
  527.   
  528. --- 201,207 ----
  529.           SHELL=/bin/sh
  530.       fi
  531.       PS1=$PROMPT
  532. !     export SHELL PS1 EDITOR PATH PROMPT HOSTNAME CDPATH
  533.   ;;
  534.   esac
  535.   
  536. ***************
  537. *** 168,192 ****
  538.   case "$_INIT_" in
  539.   *log*) ;;
  540.   *)    _INIT_="$_INIT_"log
  541. !     if [ $TTY != none -a "$0" != "-su" -a "$LOGNAME" = "`logname`" -a ! -f ~/.hushlogin ]
  542.       then
  543. !         case $TERM in
  544. !         network|unknown|dialup|"") 
  545. !             echo $N "Enter terminal type [$defterm]: $C" 1>&2
  546. !             read tmpterm
  547. !             TERM=${tmpterm:-$defterm}
  548.               ;;
  549.           esac
  550. !         # set up desired tty modes
  551. !         stty intr '^c'
  552.           case $TERM in
  553. !         wy50)    stty erase '^h';;
  554. !         *)    stty erase '^?';;
  555.           esac
  556. -         # welcome first time users
  557. -         [ -r ${LOCAL}/etc/1stlogin.ann -a ! -f $HOME/... ] && \
  558. -             . ${LOCAL}/etc/1stlogin.ann
  559.           # not all of the following are appropriate at all sites
  560.           # Sun's don't need to cat /etc/motd for instance
  561.           case "$OS" in
  562. --- 209,237 ----
  563.   case "$_INIT_" in
  564.   *log*) ;;
  565.   *)    _INIT_="$_INIT_"log
  566. !     case "$SINGLE" in
  567. !     y)    ;;
  568. !     *)
  569. !     if [ TTY != none -a "$0" != "-su" -a "$LOGNAME" = "`logname`" -a ! -f ~/.hushlogin ]
  570.       then
  571. !         case $OS in
  572. !         B.O.S.)
  573. !             case $TTY in
  574. !             ttyp*)    stty sane    # problems with telnetd
  575. !                 ;;
  576. !             esac
  577.               ;;
  578.           esac
  579. !         # ensure known state
  580. !         stty isig icanon intr '^c' erase '^h' kill '^u' eof '^d' 
  581. !         mesg y
  582.           case $TERM in
  583. !         network|unknown|dialup|"") 
  584. !           echo ${_N_} "Enter terminal type [$defterm]: ${_C_}" 1>&2
  585. !           read tmpterm
  586. !           TERM=${tmpterm:-$defterm}
  587. !           ;;
  588.           esac
  589.           # not all of the following are appropriate at all sites
  590.           # Sun's don't need to cat /etc/motd for instance
  591.           case "$OS" in
  592. ***************
  593. *** 211,217 ****
  594.               [ -x /usr/bin/news ] && /usr/bin/news -n
  595.               ;;
  596.           esac
  597. !         [ -x /usr/games/fortune ] && /usr/games/fortune -a
  598.           # remind folk who turned on reply.pl to turn it off.
  599.           if [ -f $HOME/.forward ]; then
  600.               echo "Your mail is being forwarded to:"
  601. --- 256,262 ----
  602.               [ -x /usr/bin/news ] && /usr/bin/news -n
  603.               ;;
  604.           esac
  605. ! #        [ -x /usr/games/fortune ] && /usr/games/fortune -a
  606.           # remind folk who turned on reply.pl to turn it off.
  607.           if [ -f $HOME/.forward ]; then
  608.               echo "Your mail is being forwarded to:"
  609. ***************
  610. *** 221,230 ****
  611.               fi
  612.           fi
  613.       fi
  614. !     unset tmpterm defterm C N
  615. !     TERM=${TERM:-unknown}
  616.       export TERM TTY
  617.   ;;
  618.   esac
  619.   # Handle X-terminals if necessary
  620. ! [ -f /etc/profile.X11 ] && . /etc/profile.X11
  621. --- 266,278 ----
  622.               fi
  623.           fi
  624.       fi
  625. !     unset tmpterm defterm C N _C_ _N_
  626. !     esac
  627. !     case "$TERM" in
  628. !     network|unknown|"")    TERM=vt100;;
  629. !     esac
  630.       export TERM TTY
  631.   ;;
  632.   esac
  633.   # Handle X-terminals if necessary
  634. ! [ "$SINGLE" = n -a -f /etc/profile.X11 ] && . /etc/profile.X11
  635. *** etc/sys_config.sh.old    Tue May 12 13:42:00 1992
  636. --- etc/sys_config.sh    Mon Aug 10 22:00:14 1992
  637. ***************
  638. *** 14,29 ****
  639.   #
  640.   # SEE ALSO:
  641.   #    /etc/profile
  642.   #
  643. - # AMENDED:
  644. - #    91/11/05 22:09:08 (rook)
  645. - #
  646. - # RELEASED:
  647. - #    91/11/05 22:09:09 v1.3
  648. - #
  649. - # SCCSID:
  650. - #    @(#)sys_config.sh 1.3 91/11/05 22:09:08 (rook)
  651. - #
  652.   #    @(#)Copyright (c) 1991 Simon J. Gerraty
  653.   #
  654.   #    This file is provided in the hope that it will
  655. --- 14,23 ----
  656.   #
  657.   # SEE ALSO:
  658.   #    /etc/profile
  659. + # RCSid:
  660. + #    $Id: sys_config.sh,v 1.2 1992/08/10 12:00:14 sjg Exp $
  661.   #
  662.   #    @(#)Copyright (c) 1991 Simon J. Gerraty
  663.   #
  664.   #    This file is provided in the hope that it will
  665. ***************
  666. *** 57,68 ****
  667.   OS=${OS:-`eval $uname -s`}
  668.   HOSTNAME=${HOSTNAME:-`eval $uname -n`}
  669.   
  670. ! # set which ever is required to not produce a linefeed 
  671. ! # in an echo(1)
  672. ! case $OS in
  673. ! SunOS)    C="\c"; N="";
  674. !     ;;
  675. ! *)    C="\c"; N=""
  676. !     ;;
  677.   esac
  678. ! export OS ARCH HOSTNAME C N uname
  679. --- 51,60 ----
  680.   OS=${OS:-`eval $uname -s`}
  681.   HOSTNAME=${HOSTNAME:-`eval $uname -n`}
  682.   
  683. ! case `echo -n ""` in
  684. ! -n*)    _C_=""; _N_="-n";;
  685. ! *)    _C_="\c"; _N_="";;
  686.   esac
  687. ! N="${_N_}"
  688. ! C="${_C_}"
  689. ! export OS ARCH HOSTNAME uname
  690. *** ksh.1.old    Tue May 12 13:42:00 1992
  691. --- ksh.1    Mon Aug 10 21:59:15 1992
  692. ***************
  693. *** 1,10 ****
  694. ! .\" $Id: ksh.1,v 1.1 1992/05/02 13:26:52 sjg Exp $
  695.   .nr OJ 1 \" Job Control
  696.   .nr OE 1 \" Command Editing
  697.   .nr OB 1 \" BSD enhanced ulimit options
  698.   .ds OK [\|
  699.   .ds CK \|]
  700. ! .TH KSH 1 "April 1992"
  701.   .SH NAME
  702.   ksh \- Bourne / Korn Shell (Public Domain)
  703.   .SH SYNOPSIS
  704. --- 1,10 ----
  705. ! .\" $Id: ksh.1,v 1.2 1992/08/10 11:59:15 sjg Exp $
  706.   .nr OJ 1 \" Job Control
  707.   .nr OE 1 \" Command Editing
  708.   .nr OB 1 \" BSD enhanced ulimit options
  709.   .ds OK [\|
  710.   .ds CK \|]
  711. ! .TH KSH 1 "July 1992"
  712.   .SH NAME
  713.   ksh \- Bourne / Korn Shell (Public Domain)
  714.   .SH SYNOPSIS
  715. ***************
  716. *** 43,48 ****
  717. --- 43,49 ----
  718.   .S "\fB(\fP list \fB)\fP"
  719.   .S "\fB{\fP list \fB;\fP \fB}\fP"
  720.   .S "\fBfor\fP name { \fBin\fP { word }* }? \fBdo\fP list \fB;\fP \fBdone\fP"
  721. + .S "\fBselect\fP name { \fBin\fP { word }* }? \fBdo\fP list \fB;\fP \fBdone\fP"
  722.   .S "{ \fBwhile\fP | \fBuntil\fP } list \fB;\fP \fBdo\fP list \fB;\fP \fBdone\fP"
  723.   .S "\fBif\fP list \fB;\fP \fBthen\fP list \fB;\fP { \fBelif\fP list \fB;\fP \fBthen\fP list \fB;\fP }* { \fBelse\fP list \fB;\fP }?\fBfi\fP"
  724.   .S "\fBcase\fP name \fBin\fP { \fB(\fP word { \fB|\fP word } \fB)\fP list \fB;;\fP }* \fBesac\fP"
  725. ***************
  726. *** 64,69 ****
  727. --- 65,84 ----
  728.   .S "pipe \fB||\fP cond"
  729.   .IP pipe:
  730.   .S "statement { \fB|\fP statement }*"
  731. + .SS The select statement
  732. + The \fBselect\fP statement provides an automatic method of presenting the
  733. + user with a menu selection from several options.
  734. + The \fIwords\fP given in the list are printed on standard error, each
  735. + preceded by a number.
  736. + Typing the number on standard input sets the variable \fIname\fP to the
  737. + word that was selected.
  738. + The data that was typed is preserved in a variable called REPLY.
  739. + The contents of the loop are then executed using the selected value.
  740. + A new prompt PS3 is used to indicate that a number should be typed in
  741. + to choose a value from the menu.
  742. + .LP
  743. + Menus will continue to be presented until an interrupt is received or
  744. + end-of-file is typed on input.
  745.   .SS Alias expansion
  746.   Alias expansion occurs when the first word of a
  747.   statement is a defined alias,
  748. ***************
  749. *** 70,75 ****
  750. --- 85,99 ----
  751.   except when that alias is already being expanded.
  752.   It also occurs after the expansion of an alias whose
  753.   definition ends with a space.
  754. + .SS Alternation
  755. + Csh provides a filename expansion method known as alternation.
  756. + This has been added into this version of ksh.
  757. + When performing filename subsitution, you can get the shell to create
  758. + a set of strings for you. For example, `exampl{a,b,c,d,e}' will expand
  759. + to ``exampla examplb examplc exampld example''.
  760. + A comma separated set of strings in curly braces 
  761. + will be expanded into a set of strings that are passed into the command.
  762. + The strings are not sorted.
  763.   .SS Shell variables
  764.   The following standard special variables exist:
  765.   \fB!\fP, \fB#\fP, \fB$\fP, \fB\-\fP, \fB?\fP.
  766. ***************
  767. *** 91,101 ****
  768.   \fBEDITOR\fP and finally \fBVISUAL\fP to try and determin what
  769.   command line edit mode to use.  Note that this is not strictly
  770.   ksh compatible behaviour.
  771.   .IP IFS
  772.   \fIInternal field separator\fP,
  773.   used during substitution and the \fIread\fP command.
  774. - .IP HOME
  775. - The default directory for the \fIcd\fP command.
  776.   .IP MAIL
  777.   If set, the user will be informed of the arrival of mail
  778.   in the named file.  This variable is ignored if
  779. --- 115,134 ----
  780.   \fBEDITOR\fP and finally \fBVISUAL\fP to try and determin what
  781.   command line edit mode to use.  Note that this is not strictly
  782.   ksh compatible behaviour.
  783. + .IP COLUMNS
  784. + The width to use for the commandline editing (emacs mode only).
  785. + .IP HISTFILE
  786. + The name of the file used to store history.
  787. + If defined, history will be loaded from this file on startup.
  788. + Also, several invocations of the shell running on the same machine
  789. + will share history if their HISTFILE variables all point at the same file.
  790. + .IP HISTSIZE
  791. + The number of commands normally stored for history, default 128.
  792. + .IP HOME
  793. + The default directory for the \fIcd\fP command.
  794.   .IP IFS
  795.   \fIInternal field separator\fP,
  796.   used during substitution and the \fIread\fP command.
  797.   .IP MAIL
  798.   If set, the user will be informed of the arrival of mail
  799.   in the named file.  This variable is ignored if
  800. ***************
  801. *** 129,146 ****
  802.   The number of seconds since the shell timer was started or
  803.   reset.  Assigning an integer value to this variable resets
  804.   the timer.
  805. - .IP COLUMNS
  806. - The width to use for the commandline editing (emacs mode only).
  807. - .IP HISTFILE
  808. - The name of the file to read initial history from.  The default
  809. - is "\fB$HOME/.pdksh_hist\fP".  When the shell exits it will
  810. - overwrite this file with its current history.  This behaviour
  811. - will almost certainly cause grief when multiple shells are being
  812. - run by the same user.  Making the file read-only will allow each
  813. - shell to start with a set history and avoid overwriting the
  814. - file.
  815. - .IP HISTSIZE
  816. - The number of history items to save in \fBHISTFILE\fP.
  817.   .SS Substitution
  818.   In addition to the System Vr2 substitutions,
  819.   the following are available.
  820. --- 162,167 ----
  821. ***************
  822. *** 495,503 ****
  823.   .br
  824.   bind '^XC'=forward-char
  825.   .br
  826. ! bind '^XC'=backward-char
  827.   .br
  828. ! will bind the arrow keys on an ANSI terminal.  Of course some escape
  829.   sequences won't work out quite that nicely.
  830.   .TP
  831.   \fBbind -m\fP \*(OK \fIstring\fP \*(CK = \*(OK \fIsubstitute\fP \*(CK
  832. --- 516,524 ----
  833.   .br
  834.   bind '^XC'=forward-char
  835.   .br
  836. ! bind '^XD'=backward-char
  837.   .br
  838. ! will bind the arrow keys on an ANSI terminal, or xterm.  Of course some escape
  839.   sequences won't work out quite that nicely.
  840.   .TP
  841.   \fBbind -m\fP \*(OK \fIstring\fP \*(CK = \*(OK \fIsubstitute\fP \*(CK
  842. ***************
  843. *** 809,819 ****
  844.   .LP
  845.   System V and Korn modifications by Eric Gisin,
  846.   with contributions by
  847. ! Ron Natalie, Arnold Robbins, Doug Gwyn, Erik Baalbergen, 
  848. ! AT&T\ (getopt(3)), John McMillan and Simon Gerraty.
  849.   .SH DIFFERENCES FROM AT&T VERSION
  850. ! The \fBselect\fP statement is not implemented.
  851.   Variable arrays are not implemented.
  852.   Variable attributes other than integer are not implemented.
  853.   The \fBERR\fP and \fBEXIT\fP traps are not implemented for functions.
  854. --- 830,839 ----
  855.   .LP
  856.   System V and Korn modifications by Eric Gisin,
  857.   with contributions by
  858. ! Ron Natalie, Arnold Robbins, Doug Gwyn, Erik Baalbergen, AT&T (getopt(3)),
  859. ! John McMillan, Simon Gerraty and Peter Collinson.
  860.   .SH DIFFERENCES FROM AT&T VERSION
  861. ! Csh-style alternations are implemented.
  862.   Variable arrays are not implemented.
  863.   Variable attributes other than integer are not implemented.
  864.   The \fBERR\fP and \fBEXIT\fP traps are not implemented for functions.
  865. *** sh/ChangeLog.old    Tue May 12 13:42:00 1992
  866. --- sh/ChangeLog    Mon Aug 10 22:02:13 1992
  867. ***************
  868. *** 1,3 ****
  869. --- 1,28 ----
  870. + Mon Aug  3 22:41:17 1992  Simon J. Gerraty  (sjg@zen)
  871. +     * emacs.c: correctly bind <ESC><erase>.
  872. +     * var.c: treat COLUMNS and FCEDIT as special.
  873. + Sat Aug  1 17:17:02 1992  Simon J. Gerraty  (sjg@zen)
  874. +     * Incorporated massive contribution from Peter Collinson
  875. +     includes new features (refer to ../Changes.pc) and support for
  876. +     BSDI's BSD/386.
  877. +     * emacs.c: new command complete-list provided by
  878. +     Neil.Smithline@eng.sun.com this nicer than the standard ksh
  879. +     file completion.  Define COMPLETE_LIST to bind this to <ESC><ESC>
  880. +     by default.
  881. + Sat May 30 15:44:56 1992  Simon J. Gerraty  (sjg@zen)
  882. +     * added flag XXWHL in tree.h, used by execute() when calling
  883. +     exchild() to indicate that stdin should not be invalidated.  This
  884. +     corrects handling of:  
  885. +          ls | while read f; do ls -l $f; done
  886. +     Thanks to Bruce Momjian for tracking down the fault.
  887.   Tue May 12 19:23:17 1992  Simon J. Gerraty  (sjg@zen)
  888.   
  889.       * Fix bug in init_editmode() if EMACS and VI are not both defined.
  890. *** sh/Makefile.old    Tue May 12 13:42:00 1992
  891. --- sh/Makefile    Mon Aug 10 22:02:18 1992
  892. ***************
  893. *** 1,5 ****
  894.   # PD Bourne/Korn Shell
  895. ! # $Id: Makefile,v 1.2 1992/04/25 08:33:03 sjg Exp $
  896.   
  897.   SHELL = /bin/sh
  898.   MAKE  = make
  899. --- 1,5 ----
  900.   # PD Bourne/Korn Shell
  901. ! # $Id: Makefile,v 1.3 1992/08/10 12:02:18 sjg Exp $
  902.   
  903.   SHELL = /bin/sh
  904.   MAKE  = make
  905. ***************
  906. *** 48,57 ****
  907.   # XOPTS=
  908.   # XOBJS=
  909.   #
  910.   
  911.   #CONFIG= -D_SYSV
  912.   #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
  913. ! CONFIG= -D_BSD
  914.   
  915.   
  916.   STD=../std
  917. --- 48,61 ----
  918.   # XOPTS=
  919.   # XOBJS=
  920.   #
  921. + # BSD/386
  922. + # CONFIG= -D_BSDI -D_POSIX_TERM -D_POSIX_SOURCE
  923. + # XOPTS=
  924. + # XOBJS=
  925.   
  926.   #CONFIG= -D_SYSV
  927.   #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
  928. ! CONFIG= -D_BSD -DCOMPLEX_HISTORY
  929.   
  930.   
  931.   STD=../std
  932. *** sh/config.h.old    Tue May 12 13:42:00 1992
  933. --- sh/config.h    Mon Aug 10 22:02:20 1992
  934. ***************
  935. *** 1,7 ****
  936.   /*
  937.    * Configuration file for the PD ksh
  938.    *
  939. !  * RCSid: $Id: config.h,v 1.3 1992/05/03 08:28:59 sjg Exp $
  940.    */
  941.   
  942.   #ifndef    _CONFIG_H
  943. --- 1,7 ----
  944.   /*
  945.    * Configuration file for the PD ksh
  946.    *
  947. !  * RCSid: $Id: config.h,v 1.4 1992/08/10 12:02:20 sjg Exp $
  948.    */
  949.   
  950.   #ifndef    _CONFIG_H
  951. ***************
  952. *** 49,52 ****
  953. --- 49,67 ----
  954.   /* #define    SILLY            /* Game of life in EMACS mode */
  955.   /* #define    SWTCH            /* Handle SWTCH for shl(1) */
  956.   
  957. + #define COMPLETE_LIST            /* default to Emacs style completion */
  958. + /*
  959. +  * ALTERNATIONS is csh not ksh, but it is such a nice feature...
  960. +  */
  961. + #define ALTERNATIONS            /* csh {a,b,c} arg expansion */
  962. + /* #define COMPLEX_HISTORY            /* Peter Collinson's history */
  963. + /*
  964. +  * if you don't have mmap() you can't use Peter Collinson's history
  965. +  * mechanism.  If that is the case, then define EASY_HISTORY
  966. +  */
  967. + #if !defined(COMPLEX_HISTORY) || defined(NO_MMAP)
  968. + # define EASY_HISTORY            /* sjg's trivial history file */
  969. + #endif
  970. +   
  971.   #endif    /* _CONFIG_H */
  972. *** sh/edit.c.old    Tue May 12 13:42:00 1992
  973. --- sh/edit.c    Mon Aug 10 22:02:25 1992
  974. ***************
  975. *** 7,13 ****
  976.   #if defined(EMACS) || defined(VI)
  977.   
  978.   #ifndef lint
  979. ! static char *RCSid = "$Id: edit.c,v 1.4 1992/05/12 09:30:31 sjg Exp $";
  980.   #endif
  981.   
  982.   #include "stdh.h"
  983. --- 7,13 ----
  984.   #if defined(EMACS) || defined(VI)
  985.   
  986.   #ifndef lint
  987. ! static char *RCSid = "$Id: edit.c,v 1.5 1992/08/10 12:02:25 sjg Exp $";
  988.   #endif
  989.   
  990.   #include "stdh.h"
  991. ***************
  992. *** 48,54 ****
  993.     {
  994.       setup_done = 42;        /* these get done once only */
  995.       x_do_init = 1;
  996. -     x_cols = 80;
  997.       x_col = 0;
  998.       ed_erase = -1, ed_kill = -1, ed_werase = -1, ed_intr = -1, ed_quit = -1;
  999.       x_adj_ok = 1;
  1000. --- 48,53 ----
  1001. ***************
  1002. *** 212,219 ****
  1003. --- 211,222 ----
  1004.   #endif
  1005.   #endif
  1006.   #else
  1007. + #ifdef _POSIX_TERM
  1008. + static    struct termios cb, cborig;
  1009. + #else
  1010.   static    struct termio cb, cborig;
  1011.   #endif
  1012. + #endif
  1013.   
  1014.   /* initialize editing mode */
  1015.   void
  1016. ***************
  1017. *** 261,267 ****
  1018. --- 264,274 ----
  1019.   #endif
  1020.   #endif
  1021.   #else /* !_BSD */
  1022. + #ifdef _POSIX_TERM
  1023. +     (void) tcgetattr(ttyfd, &cborig);
  1024. + #else
  1025.       (void)ioctl(ttyfd, TCGETA, &cborig);
  1026. + #endif
  1027.       if ((cborig.c_lflag & ECHO) == 0)
  1028.           x_noecho = 1;
  1029.       cb = cborig;
  1030. ***************
  1031. *** 347,352 ****
  1032. --- 354,362 ----
  1033.       x_cur_mode = onoff;
  1034.   
  1035.       if (onoff)  {
  1036. + #ifdef _POSIX_TERM
  1037. +         (void) tcsetattr(ttyfd, TCSADRAIN, &cb);
  1038. + #else
  1039.   #ifndef TCSETAW                /* e.g. Cray-2 */
  1040.           /* first wait for output to drain */
  1041.   #ifdef TCSBRK
  1042. ***************
  1043. *** 361,368 ****
  1044. --- 371,382 ----
  1045.   #else
  1046.           (void)ioctl(ttyfd, TCSETAW, &cb);
  1047.   #endif
  1048. + #endif
  1049.       }
  1050.       else {
  1051. + #ifdef _POSIX_TERM
  1052. +         (void) tcsetattr(ttyfd, TCSADRAIN, &cborig);
  1053. + #else
  1054.   #ifndef TCSETAW                /* e.g. Cray-2 */
  1055.           /* first wait for output to drain */
  1056.   #ifdef TCSBRK
  1057. ***************
  1058. *** 378,383 ****
  1059. --- 392,398 ----
  1060.   #else
  1061.           (void)ioctl(ttyfd, TCSETAW, &cborig);
  1062.   #endif
  1063. + #endif
  1064.       }
  1065.       return prev;
  1066.   }
  1067. ***************
  1068. *** 436,470 ****
  1069.   {
  1070.     static char *ev[] = { "FCEDIT", "EDITOR", "VISUAL", NULL };
  1071.     register int i;
  1072. !   register char *rcp, *rcp2;
  1073.   
  1074.     for (i = 0; ev[i]; i++)
  1075.     {
  1076. !     if ((rcp = getenv(ev[i])) && *rcp)
  1077.         break;
  1078.     }
  1079.     if (ev[i] && rcp)
  1080.     {
  1081. !     if (rcp2 = strrchr(rcp, '/'))
  1082. !       rcp = ++rcp2;
  1083.   #ifdef EMACS
  1084. !     if (strstr(rcp, "emacs"))
  1085. !     {
  1086. !       flag[FVI] = 0;
  1087. !       flag[FEMACS] = 1;
  1088. !     }
  1089.   #endif
  1090.   #if defined(EMACS) && defined(VI)
  1091. !     else
  1092.   #endif
  1093.   #ifdef VI
  1094. !       if (strstr(rcp, "vi"))
  1095. !       {
  1096. !     flag[FVI] = 1;
  1097. !     flag[FEMACS] = 0;
  1098. !       }
  1099.   #endif
  1100. -   }
  1101. -   return 0;
  1102.   }
  1103.   #endif
  1104. --- 451,500 ----
  1105.   {
  1106.     static char *ev[] = { "FCEDIT", "EDITOR", "VISUAL", NULL };
  1107.     register int i;
  1108. !   register char *rcp;
  1109.   
  1110.     for (i = 0; ev[i]; i++)
  1111.     {
  1112. ! #ifdef DEBUG
  1113. !     (void) fprintf(stderr, "check %s\n", ev[i]);
  1114. ! #endif
  1115. !     if ((rcp = strval(global(ev[i]))) && *rcp)
  1116.         break;
  1117.     }
  1118.     if (ev[i] && rcp)
  1119.     {
  1120. !     set_editmode(rcp);
  1121. !   }
  1122. !   return 0;
  1123. ! }
  1124. ! void
  1125. ! set_editmode(ed)
  1126. !   char *ed;
  1127. ! {
  1128. !   register char *rcp;
  1129. !   
  1130. ! #ifdef DEBUG
  1131. !   (void) fprintf(stderr, "set_editmode(%s)\n", ed);
  1132. ! #endif
  1133. !   if (rcp = strrchr(ed, '/'))
  1134. !     ed = ++rcp;
  1135.   #ifdef EMACS
  1136. !   if (strstr(ed, "emacs"))
  1137. !   {
  1138. !     flag[FVI] = 0;
  1139. !     flag[FEMACS] = 1;
  1140. !   }
  1141.   #endif
  1142.   #if defined(EMACS) && defined(VI)
  1143. !   else
  1144.   #endif
  1145.   #ifdef VI
  1146. !     if (strstr(ed, "vi"))
  1147. !     {
  1148. !       flag[FVI] = 1;
  1149. !       flag[FEMACS] = 0;
  1150. !     }
  1151.   #endif
  1152.   }
  1153.   #endif
  1154. *** sh/edit.h.old    Tue May 12 13:42:00 1992
  1155. --- sh/edit.h    Mon Aug 10 22:02:28 1992
  1156. ***************
  1157. *** 8,14 ****
  1158.    *      
  1159.    *
  1160.    * RCSid:
  1161. !  *      $Id: edit.h,v 1.2 1992/04/25 08:33:28 sjg Exp $
  1162.    *
  1163.    */
  1164.   
  1165. --- 8,14 ----
  1166.    *      
  1167.    *
  1168.    * RCSid:
  1169. !  *      $Id: edit.h,v 1.3 1992/08/10 12:02:28 sjg Exp $
  1170.    *
  1171.    */
  1172.   
  1173. ***************
  1174. *** 39,45 ****
  1175.    */
  1176.   EXTERN int    x_adj_done;
  1177.   
  1178. ! EXTERN int    x_cols;
  1179.   EXTERN int    x_col;
  1180.   EXTERN int    x_displen;
  1181.   EXTERN int    x_arg;        /* general purpose arg */
  1182. --- 39,45 ----
  1183.    */
  1184.   EXTERN int    x_adj_done;
  1185.   
  1186. ! EXTERN int    x_cols _I_(80);    /* default to 80 cols */
  1187.   EXTERN int    x_col;
  1188.   EXTERN int    x_displen;
  1189.   EXTERN int    x_arg;        /* general purpose arg */
  1190. *** sh/emacs.c.old    Tue May 12 13:42:00 1992
  1191. --- sh/emacs.c    Mon Aug 10 22:02:31 1992
  1192. ***************
  1193. *** 10,16 ****
  1194.   #ifdef EMACS
  1195.   
  1196.   #ifndef lint
  1197. ! static char *RCSid = "$Id: emacs.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  1198.   #endif
  1199.   
  1200.   #include "stdh.h"
  1201. --- 10,16 ----
  1202.   #ifdef EMACS
  1203.   
  1204.   #ifndef lint
  1205. ! static char *RCSid = "$Id: emacs.c,v 1.3 1992/08/10 12:02:31 sjg Exp $";
  1206.   #endif
  1207.   
  1208.   #include "stdh.h"
  1209. ***************
  1210. *** 150,155 ****
  1211. --- 150,156 ----
  1212.   static int      x_enumerate ARGS((int c));
  1213.   static int      x_comp_file ARGS((int c));
  1214.   static int      x_list_file ARGS((int c));
  1215. + static int      x_comp_list ARGS((int c));
  1216.   static void     compl_dec   ARGS((int type));
  1217.   static void     compl_file  ARGS((int type));
  1218.   static void     compl_command ARGS((int type));
  1219. ***************
  1220. *** 202,208 ****
  1221. --- 203,215 ----
  1222.       {x_stuff,     "stuff",        0,     0,    0 },
  1223.       {x_transpose,    "transpose-chars",    0, CTRL('T'),    0 },
  1224.   #endif
  1225. + #ifdef COMPLETE_LIST
  1226. +     {x_complete,    "complete",        1,     0,    0 },
  1227. +      {x_comp_list,    "complete-list",    1, CTRL('['),    0 },
  1228. + #else
  1229.       {x_complete,    "complete",        1, CTRL('['),    0 },
  1230. +      {x_comp_list,    "complete-list",    1,      0,    0 },
  1231. + #endif
  1232.       {x_enumerate,    "list",            1,    '?',    0 },
  1233.       {x_comp_file,    "complete-file",    1, CTRL('X'),    0 },
  1234.       {x_comp_comm,    "complete-command",    2, CTRL('['),    0 },
  1235. ***************
  1236. *** 275,285 ****
  1237.           x_nextcmdp = NULL;
  1238.       }
  1239.   
  1240. -     /* <sjg@sun0> this may not be correct */
  1241. -     if ((i = atoi(strval(global("COLUMNS")))) > 0)
  1242. -       x_cols = i;
  1243. -     else
  1244. -       x_cols = 80;
  1245.       x_col = promptlen(prompt);
  1246.       x_adj_ok = 1;
  1247.       x_displen = x_cols - 2 - x_col;
  1248. --- 282,287 ----
  1249. ***************
  1250. *** 1219,1224 ****
  1251. --- 1221,1227 ----
  1252.       x_tab[0][werase] = xft_werase;
  1253.       x_tab[0][intr] = xft_intr;
  1254.       x_tab[0][quit] = xft_quit;
  1255. +     x_tab[1][erase] = xft_werase;
  1256.   }
  1257.   
  1258.   static int
  1259. ***************
  1260. *** 1448,1460 ****
  1261.       compl_file(0);
  1262.       return KSTD;
  1263.   }
  1264.   
  1265. ! static void
  1266. ! compl_dec(type)
  1267. ! {
  1268. !     char    *cp;
  1269. !     cp = xcp;
  1270.       while (cp != xbuf && !iscfs(*cp))
  1271.           cp--;
  1272.       if (cp == xbuf && strchr(cp, '/') == NULL)
  1273. --- 1451,1463 ----
  1274.       compl_file(0);
  1275.       return KSTD;
  1276.   }
  1277. + static int
  1278. + x_comp_list(c)   {
  1279. +     compl_dec(2);
  1280. +     return KSTD;
  1281. + }
  1282.   
  1283. ! static void compl_dec(type) {     char    *cp;     cp = xcp; 
  1284.       while (cp != xbuf && !iscfs(*cp))
  1285.           cp--;
  1286.       if (cp == xbuf && strchr(cp, '/') == NULL)
  1287. ***************
  1288. *** 1478,1483 ****
  1289. --- 1481,1487 ----
  1290.       int    len;
  1291.       int    multi = 0;
  1292.   
  1293. +     /* type == 0 for list, 1 for complete and 2 for complete-list */
  1294.       str = xcp;
  1295.       cp = buf;
  1296.       xp = str;
  1297. ***************
  1298. *** 1492,1501 ****
  1299.           xp++;
  1300.       while (*xp == '<' || *xp == '>')
  1301.           xp++;
  1302. !     if (type)
  1303.           while (*xcp && !iscfs(*xcp))
  1304.               x_zotc(*xcp++);
  1305. !     else {
  1306.           x_maxlen = 0;
  1307.           XPinit(words, 16);
  1308.       }
  1309. --- 1496,1506 ----
  1310.           xp++;
  1311.       while (*xp == '<' || *xp == '>')
  1312.           xp++;
  1313. !     if (type) {            /* for complete */
  1314.           while (*xcp && !iscfs(*xcp))
  1315.               x_zotc(*xcp++);
  1316. !     }
  1317. !     if (type != 1) {        /* for list */
  1318.           x_maxlen = 0;
  1319.           XPinit(words, 16);
  1320.       }
  1321. ***************
  1322. *** 1526,1534 ****
  1323.           cp = dp->d_name;
  1324.           if (cp[0] == '.' &&
  1325.               (cp[1] == '\0' || (cp[1] == '.' && cp[2] == '\0')))
  1326. !             continue; /* always ignore . and .. */
  1327. !         if (strncmp(lastp, cp, len) == 0)
  1328. !             if (type)  {
  1329.                   if (loc == -1)  {
  1330.                       (void)strcpy(bug, cp);
  1331.                       loc = strlen(cp);
  1332. --- 1531,1539 ----
  1333.           cp = dp->d_name;
  1334.           if (cp[0] == '.' &&
  1335.               (cp[1] == '\0' || (cp[1] == '.' && cp[2] == '\0')))
  1336. !             continue;    /* always ignore . and .. */
  1337. !         if (strncmp(lastp, cp, len) == 0) {
  1338. !             if (type    /* for complete */) {
  1339.                   if (loc == -1)  {
  1340.                       (void)strcpy(bug, cp);
  1341.                       loc = strlen(cp);
  1342. ***************
  1343. *** 1537,1549 ****
  1344.                       loc = strmatch(bug, cp);
  1345.                       bug[loc] = 0;
  1346.                   }
  1347. !             } else
  1348.                   add_stash(dirnam, cp);
  1349.       }
  1350.       (void)closedir(dirp);
  1351.   
  1352. !     if (type) {
  1353. !         if (loc <= 0)  {
  1354.               x_putc(BEL);
  1355.               return;
  1356.           }
  1357. --- 1542,1558 ----
  1358.                       loc = strmatch(bug, cp);
  1359.                       bug[loc] = 0;
  1360.                   }
  1361. !             }
  1362. !             if (type != 1) { /* for list */
  1363.                   add_stash(dirnam, cp);
  1364. +             }
  1365. +         }
  1366.       }
  1367.       (void)closedir(dirp);
  1368.   
  1369. !     if (type) {            /* for complete */
  1370. !         if (loc < 0 ||
  1371. !             (loc == 0 && type != 2))  {
  1372.               x_putc(BEL);
  1373.               return;
  1374.           }
  1375. ***************
  1376. *** 1564,1571 ****
  1377.               else
  1378.                   x_ins(" ");
  1379.           }
  1380. !     } else
  1381.           list_stash();
  1382.   }
  1383.   
  1384.   static void
  1385. --- 1573,1583 ----
  1386.               else
  1387.                   x_ins(" ");
  1388.           }
  1389. !     }
  1390. !     if (type == 0 ||        /* if list */
  1391. !         (type == 2 && multi)) {    /* or complete-list and ambiguous */
  1392.           list_stash();
  1393. +     }
  1394.   }
  1395.   
  1396.   static void
  1397. ***************
  1398. *** 1581,1586 ****
  1399. --- 1593,1599 ----
  1400.       int  multi;
  1401.       int  loc;
  1402.   
  1403. +     /* type == 0 for list, 1 for complete and 2 for complete-list */
  1404.       str = xcp;
  1405.       cp = buf;
  1406.       xp = str;
  1407. ***************
  1408. *** 1591,1600 ****
  1409.               break;
  1410.           }
  1411.       }
  1412. !     if (type)
  1413.           while (*xcp && !iscfs(*xcp))
  1414.               x_zotc(*xcp++);
  1415. !     else {
  1416.           x_maxlen = 0;
  1417.           XPinit(words, 16);
  1418.       }
  1419. --- 1604,1613 ----
  1420.               break;
  1421.           }
  1422.       }
  1423. !     if (type)            /* for complete */
  1424.           while (*xcp && !iscfs(*xcp))
  1425.               x_zotc(*xcp++);
  1426. !     if (type != 1) {        /* for list */
  1427.           x_maxlen = 0;
  1428.           XPinit(words, 16);
  1429.       }
  1430. ***************
  1431. *** 1614,1621 ****
  1432.           klen = strlen(tp->name);
  1433.           if (klen < len)
  1434.               continue;
  1435. !         if (strncmp(buf, tp->name, len) ==0)
  1436. !             if (type)  {
  1437.                   if (loc == -1)  {
  1438.                       (void)strcpy(bug, tp->name);
  1439.                       loc = klen;
  1440. --- 1627,1634 ----
  1441.           klen = strlen(tp->name);
  1442.           if (klen < len)
  1443.               continue;
  1444. !         if (strncmp(buf, tp->name, len) ==0) {
  1445. !             if (type)  {    /* for complete */
  1446.                   if (loc == -1)  {
  1447.                       (void)strcpy(bug, tp->name);
  1448.                       loc = klen;
  1449. ***************
  1450. *** 1624,1635 ****
  1451.                       loc = strmatch(bug, tp->name);
  1452.                       bug[loc] = 0;
  1453.                   }
  1454. !             } else
  1455.                   add_stash((char *)0, tp->name);
  1456.       }
  1457.   
  1458. !     if (type)  {
  1459. !         if (loc <= 0)  {
  1460.               x_putc(BEL);
  1461.               return;
  1462.           }
  1463. --- 1637,1652 ----
  1464.                       loc = strmatch(bug, tp->name);
  1465.                       bug[loc] = 0;
  1466.                   }
  1467. !             }
  1468. !             if (type != 1) { /* for list */
  1469.                   add_stash((char *)0, tp->name);
  1470. +             }
  1471. +         }
  1472.       }
  1473.   
  1474. !     if (type)  {            /* for complete */
  1475. !         if (loc < 0 ||
  1476. !             (loc == 0 && type != 2))  {
  1477.               x_putc(BEL);
  1478.               return;
  1479.           }
  1480. ***************
  1481. *** 1637,1644 ****
  1482.           x_ins(cp);
  1483.           if (!multi)
  1484.               x_ins(" ");
  1485. !     } else
  1486.           list_stash();
  1487.   }
  1488.   
  1489.   static int
  1490. --- 1654,1667 ----
  1491.           x_ins(cp);
  1492.           if (!multi)
  1493.               x_ins(" ");
  1494. !         else if (type == 2)    /* complete and list rest */
  1495. !             list_stash();
  1496. !     }
  1497. !     if (type == 0 ||        /* if list */
  1498. !         (type == 2 && multi)) {    /* or complete-list and ambiguous */
  1499.           list_stash();
  1500. +     }
  1501.   }
  1502.   
  1503.   static int
  1504. *** sh/eval.c.old    Tue May 12 13:42:00 1992
  1505. --- sh/eval.c    Mon Aug 10 22:02:35 1992
  1506. ***************
  1507. *** 3,9 ****
  1508.    */
  1509.   
  1510.   #ifndef lint
  1511. ! static char *RCSid = "$Id: eval.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  1512.   #endif
  1513.   
  1514.   #include "stdh.h"
  1515. --- 3,9 ----
  1516.    */
  1517.   
  1518.   #ifndef lint
  1519. ! static char *RCSid = "$Id: eval.c,v 1.3 1992/08/10 12:02:35 sjg Exp $";
  1520.   #endif
  1521.   
  1522.   #include "stdh.h"
  1523. ***************
  1524. *** 48,53 ****
  1525. --- 48,58 ----
  1526.   static char *   debunk      ARGS((char *cp));
  1527.   static char *   tilde       ARGS((char *acp));
  1528.   static char *   homedir     ARGS((char *name));
  1529. + #ifdef ALTERNATIONS
  1530. + static    int    alt_expand  ARGS((char *, XPtrV *, int));
  1531. + static    int    alt_count   ARGS((char *));
  1532. + static    int    alt_scan    ARGS((char **, char **, char,     int));
  1533. + #endif
  1534.   
  1535.   int    ifs0 = ' ';        /* todo: first char of $IFS */
  1536.   
  1537. ***************
  1538. *** 112,117 ****
  1539. --- 117,150 ----
  1540.       return cp;
  1541.   }
  1542.   
  1543. + /*
  1544. +  * expand string - return only one component
  1545. +  * used from iosetup to expand redirection files
  1546. +  */
  1547. + char *
  1548. + evalonestr(cp, f)
  1549. +     register char *cp;
  1550. +     int f;
  1551. + {
  1552. +     XPtrV w;
  1553. +     XPinit(w, 1);
  1554. +     expand(cp, &w, f);
  1555. +     switch (XPsize(w)) {
  1556. +     case 0:
  1557. +         cp = "";
  1558. +         break;
  1559. +     case 1:
  1560. +         cp = (char*) *XPptrv(w);
  1561. +         break;
  1562. +     default:
  1563. +         cp = evalstr(cp, f&~DOGLOB);
  1564. +         break;
  1565. +     }
  1566. +     XPfree(w);
  1567. +     return cp;
  1568. + }
  1569.   /* for nested substitution: ${var:=$var2} */
  1570.   typedef struct SubType {
  1571.       short    type;        /* [=+-?%#] action after expanded word */
  1572. ***************
  1573. *** 144,149 ****
  1574. --- 177,196 ----
  1575.       if (flag[FNOGLOB])
  1576.           f &= ~ DOGLOB;
  1577.   
  1578. + #ifdef ALTERNATIONS
  1579. + #define NOALT    BIT(8)        /* internal to this file */
  1580. +                 /* prevent endless recursion */
  1581. +     /* look for '{' in the input word */
  1582. +     if (((f & NOALT) == 0) && (f & DOGLOB) &&
  1583. +         (dp = strchr(cp, '{')) != NULL &&
  1584. +         (dp[-1] == CHAR) &&
  1585. +             !(dp[1] == CHAR && dp[2] == '}')) {
  1586. +         if (alt_expand(cp, wp, f))
  1587. +             return;
  1588. +     }
  1589. +     f &= ~NOALT;
  1590. + #endif
  1591.       Xinit(ds, dp, 128);    /* init dest. string */
  1592.       type = XBASE;
  1593.       sp = cp;
  1594. ***************
  1595. *** 496,501 ****
  1596. --- 543,748 ----
  1597.   
  1598.       return str;        /* no match, return string */
  1599.   }
  1600. + #ifdef ALTERNATIONS
  1601. + /*    (pc@hillside.co.uk)
  1602. +  *    I have decided to `fudge' alternations by picking up
  1603. +  *    the compiled command tree and working with it recursively
  1604. +  *    to generate the set of arguments
  1605. +  *    This has the advantage of making a single discrete change
  1606. +  *    to the code
  1607. +  *
  1608. +  *    This routine calls itself recursively
  1609. +  *    a)    scan forward looking for { building the output string
  1610. +  *        if none found then call expand - and exit
  1611. +  *    b)    When { found, scan forward finding the end }
  1612. +  *    c)    add first alternate to output string
  1613. +  *    d)    scan for the end of the string copying into output
  1614. +  *    e)    call routine with new string
  1615. +  *    Major complication is quoting
  1616. +  */
  1617. + static int
  1618. + alt_expand(cp, wp, f)
  1619. +     char *cp;        /* input word */
  1620. +     register XPtrV *wp;    /* output words */
  1621. +     int f;            /* DO* flags */
  1622. + {
  1623. +     char *srcp = cp;
  1624. +     char *left;        /* destination string of left hand side */
  1625. +     char *leftend;        /* end of left hand side */
  1626. +     char *alt;        /* start of alterate section */
  1627. +     char *altend;        /* end of alternate section */
  1628. +     char *ap;        /* working pointer */
  1629. +     char *right;        /* right hand side */
  1630. +     char *rp;        /* used to copy right-hand side */
  1631. +     int  maxlen;        /* max string length */
  1632. +     leftend = left = alloc((maxlen = alt_count(cp)), ATEMP);
  1633. +     
  1634. +     if (alt_scan(&srcp, &leftend, '{', 0) == 0) {
  1635. +         expand(cp, wp, f&NOALT);
  1636. +         afree(left, ATEMP);
  1637. +         return;
  1638. +     }
  1639. +     /*
  1640. +      *    we have a alternation section
  1641. +      */
  1642. +     alt = altend = alloc(maxlen, ATEMP);
  1643. +     srcp += 2;
  1644. +     if (alt_scan(&srcp, &altend, '}', 1) == 0) {
  1645. +         afree(left, ATEMP);
  1646. +         afree(alt, ATEMP);
  1647. +         errorf("Missing }.\n");
  1648. +     }
  1649. +     *altend++ = CHAR;
  1650. +     *altend++ = ',';
  1651. +     *altend = EOS;
  1652. +     /*
  1653. +      *    finally we may have a right-hand side
  1654. +      */
  1655. +     right = srcp + 2;
  1656. +     /*
  1657. +      *    glue the bits together making a new string
  1658. +      */
  1659. +     for (srcp = alt; *srcp != EOS;) {
  1660. +         ap = leftend;
  1661. +         if (alt_scan(&srcp, &ap, ',', -1) == 0) {
  1662. +             afree(left, ATEMP);
  1663. +             afree(alt, ATEMP);
  1664. +             errorf("Missing comma.\n");
  1665. +         }
  1666. +         
  1667. +         srcp += 2;
  1668. +         rp = right;
  1669. +         (void) alt_scan(&rp, &ap, EOS, 0);
  1670. +         alt_expand(left, wp, f);
  1671. +     }
  1672. +     afree(left, ATEMP);
  1673. +     afree(alt, ATEMP);
  1674. + }
  1675. + /*
  1676. +  * see how much space we need to hold this tree
  1677. +  */
  1678. + static int
  1679. + alt_count(cp)
  1680. +     register char *cp;
  1681. + {
  1682. +     register int sum = 0;
  1683. +     register char *sp;
  1684. +     while (*cp != EOS) {
  1685. +         switch(*cp) {
  1686. +           case CHAR:
  1687. +           case QCHAR:
  1688. +             sum += 2;
  1689. +             cp += 2;
  1690. +             break;
  1691. +           case OQUOTE:
  1692. +           case CQUOTE:
  1693. +           case CSUBST:
  1694. +             sum++;
  1695. +             cp++;
  1696. +             break;
  1697. +           case COMSUB:
  1698. +           case OSUBST:
  1699. +             sp = cp;
  1700. +             cp = strchr(sp, 0) + 1;
  1701. +             sum += cp - sp;
  1702. +             break;
  1703. +         }
  1704. +     }
  1705. +     return ++sum;
  1706. + }
  1707. + #ifdef __STDC__
  1708. + static int
  1709. + alt_scan(
  1710. +     char **cpp,        /* address of source pointer */
  1711. +     char **dpp,        /* address of destination pointer */
  1712. +     char endc,        /* last character we are looking for */
  1713. +     int bal)
  1714. + #else
  1715. + static int
  1716. + alt_scan(cpp, dpp, endc, bal)
  1717. +     char **cpp;        /* address of source pointer */
  1718. +     char **dpp;        /* address of destination pointer */
  1719. +     char endc;        /* last character we are looking for */
  1720. +     int bal;
  1721. + #endif
  1722. + {
  1723. +     register char *cp, *dp;
  1724. +     int quote = 0;
  1725. +     int balance = 0;
  1726. +     int usebalance = 0;
  1727. +     if (bal)
  1728. +     {    usebalance = 1;
  1729. +         balance = (bal < 1) ? 0 : 1;
  1730. +     }
  1731. +     cp = *cpp;
  1732. +     dp = *dpp;
  1733. +     while (*cp != EOS) {
  1734. +         switch (*cp) {
  1735. +           case CHAR:
  1736. +             if (quote == 1) {
  1737. +                 if (cp[1] == ']')
  1738. +                     quote = 0;
  1739. +             }
  1740. +             else
  1741. +             if (quote == 0) {
  1742. +                 if (cp[1] == '[')
  1743. +                     quote = 1;
  1744. +                 else {
  1745. +                     if (usebalance) {
  1746. +                         if (cp[1] == '{')
  1747. +                             balance++;
  1748. +                         if (cp[1] == '}')
  1749. +                             balance--;
  1750. +                         }
  1751. +                     if (cp[1] == endc && balance == 0) {
  1752. +                         *dp = EOS;
  1753. +                         *dpp = dp;
  1754. +                         *cpp = cp;
  1755. +                         return 1;
  1756. +                         }
  1757. +                 }
  1758. +             }
  1759. +           case QCHAR:
  1760. +             *dp++ = *cp++;
  1761. +           copy:
  1762. +             *dp++ = *cp++;
  1763. +             break;
  1764. +             
  1765. +           case OQUOTE:
  1766. +             quote = 1;
  1767. +             goto copy;
  1768. +           case CQUOTE:
  1769. +             quote = 0;
  1770. +             goto copy;
  1771. +           case COMSUB:
  1772. +           case OSUBST:
  1773. +             while (*dp++ = *cp++);
  1774. +             break;
  1775. +         }
  1776. +     }
  1777. +     *dp = EOS;
  1778. +     *cpp = cp;
  1779. +     *dpp = dp;
  1780. +     return 0;
  1781. + }
  1782. + #endif    /* ALTERNATIONS */
  1783.   
  1784.   /*
  1785.    * glob
  1786. *** sh/exec.c.old    Tue May 12 13:42:00 1992
  1787. --- sh/exec.c    Mon Aug 10 22:02:38 1992
  1788. ***************
  1789. *** 3,9 ****
  1790.    */
  1791.   
  1792.   #ifndef lint
  1793. ! static char *RCSid = "$Id: exec.c,v 1.3 1992/04/25 08:29:52 sjg Exp $";
  1794.   #endif
  1795.   
  1796.   #include "stdh.h"
  1797. --- 3,9 ----
  1798.    */
  1799.   
  1800.   #ifndef lint
  1801. ! static char *RCSid = "$Id: exec.c,v 1.4 1992/08/10 12:02:38 sjg Exp $";
  1802.   #endif
  1803.   
  1804.   #include "stdh.h"
  1805. ***************
  1806. *** 14,19 ****
  1807. --- 14,20 ----
  1808.   #include <fcntl.h>
  1809.   #include <sys/stat.h>
  1810.   #include "sh.h"
  1811. + #include "edit.h"
  1812.   
  1813.   static int      comexec     ARGS((struct op *t, char **vp, char **ap, int flags));
  1814.   #ifdef    SHARPBANG
  1815. ***************
  1816. *** 22,27 ****
  1817. --- 23,30 ----
  1818.   static void     iosetup     ARGS((struct ioword *iop));
  1819.   static int      herein      ARGS((char *hname, int sub));
  1820.   static void     echo        ARGS((char **vp, char **ap));
  1821. + static    char     *do_selectargs ARGS((char **ap, char *));
  1822. + static    int    selread        ARGS((void));
  1823.   
  1824.   
  1825.   /*
  1826. ***************
  1827. *** 167,172 ****
  1828. --- 170,192 ----
  1829.         Break1:
  1830.           break;
  1831.   
  1832. +       case TSELECT:
  1833. +         e.type = E_LOOP;
  1834. +         ap = (t->vars != NULL) ?
  1835. +             eval(t->vars, DOBLANK|DOGLOB|DOTILDE) : e.loc->argv + 1;
  1836. +         while ((i = setjmp(e.jbuf)))
  1837. +             if (i == LBREAK)
  1838. +                 goto Break1;
  1839. +         signal(SIGINT, trapsig); /* needs change to trapsig */
  1840. +         cp = NULL;
  1841. +         for (;;) {
  1842. +             if ((cp = do_selectargs(ap, cp)) == (char *)1)
  1843. +                 break;
  1844. +             setstr(global(t->str), cp);
  1845. +             rv = execute(t->left, 0);
  1846. +         }
  1847. +         break;
  1848. +         
  1849.         case TWHILE:
  1850.         case TUNTIL:
  1851.           e.type = E_LOOP;
  1852. ***************
  1853. *** 174,180 ****
  1854.               if (i == LBREAK)
  1855.                   goto Break2;
  1856.           while ((execute(t->left, 0) == 0) == (t->type == TWHILE))
  1857. !             rv = execute(t->right, 0);
  1858.         Break2:
  1859.           break;
  1860.   
  1861. --- 194,200 ----
  1862.               if (i == LBREAK)
  1863.                   goto Break2;
  1864.           while ((execute(t->left, 0) == 0) == (t->type == TWHILE))
  1865. !             rv = execute(t->right, XXWHL);
  1866.         Break2:
  1867.           break;
  1868.   
  1869. ***************
  1870. *** 655,661 ****
  1871.       e.savefd[iop->unit] = savefd(iop->unit);
  1872.   
  1873.       if ((iop->flag&IOTYPE) != IOHERE)
  1874. !         cp = evalstr(cp, DOTILDE);
  1875.   
  1876.       switch (iop->flag&IOTYPE) {
  1877.         case IOREAD:
  1878. --- 675,681 ----
  1879.       e.savefd[iop->unit] = savefd(iop->unit);
  1880.   
  1881.       if ((iop->flag&IOTYPE) != IOHERE)
  1882. !         cp = evalonestr(cp, DOTILDE|DOGLOB);
  1883.   
  1884.       switch (iop->flag&IOTYPE) {
  1885.         case IOREAD:
  1886. ***************
  1887. *** 772,774 ****
  1888. --- 792,948 ----
  1889.       shellf("\n");
  1890.   }
  1891.   
  1892. + /*
  1893. +  *    ksh special - the select command processing section
  1894. +  *    print the args in column form - assuming that we can
  1895. +  */
  1896. + #define    COLARGS        20
  1897. + static char *
  1898. + do_selectargs(ap, secondtime)
  1899. +     register char **ap;
  1900. +     char    *secondtime;
  1901. + {
  1902. +     char *rv;
  1903. +     register int i, c;
  1904. +     static char *replybase = NULL;
  1905. +     static int replymax;
  1906. +     static int repct;
  1907. +     static int argct;
  1908. +     
  1909. +     /*
  1910. +      * deal with REPLY variable
  1911. +      */
  1912. +     if (replybase == NULL) {
  1913. +         replybase = alloc(64, APERM);
  1914. +         replymax = 64;
  1915. +     }
  1916. +     if (!secondtime)
  1917. +         argct = pr_menu(ap, 0);
  1918. +     
  1919. +     /*
  1920. +      * and now ask for an answer
  1921. +      */
  1922. + retry:
  1923. +     shellf("%s", strval(global("PS3")));
  1924. +     fflush(shlout);
  1925. +     repct = 0;
  1926. +     i = 0;
  1927. +     rv = NULL;
  1928. +     while ((c = selread()) != EOF) {
  1929. +         if (c == -2) {
  1930. +             shellf("Read error\n");
  1931. +             rv = (char*)1;
  1932. +             break;
  1933. +         }
  1934. +         if (repct+1 >= replymax)
  1935. +         {    replymax += 64;
  1936. +             replybase = aresize(replybase, replymax, APERM);
  1937. +         }
  1938. +         if (i >= 0 && c >= '0' && c <= '9') {
  1939. +             replybase[repct++] = c;
  1940. +             if (i >= 0)
  1941. +                 i = i*10 + (c - '0');
  1942. +         }
  1943. +         else
  1944. +         if (c == '\n') {
  1945. +             if (repct == 0) {
  1946. +                 pr_menu(ap, 1);
  1947. +                 goto retry;
  1948. +             }
  1949. +                 
  1950. +             if (i >= 1 && i <= argct)
  1951. +                 rv = ap[i-1];
  1952. +             else    rv = "";
  1953. +             break;
  1954. +         } else
  1955. +             i = -1,    replybase[repct++] = c;
  1956. +     }
  1957. +     if (rv == NULL) {
  1958. +         shellf("\n");
  1959. +         rv = (char *)1;
  1960. +     }
  1961. +     replybase[repct] = '\0';
  1962. +     setstr(global("REPLY"), replybase);
  1963. +     return rv;
  1964. + }
  1965. + /*
  1966. +  *    print a select style menu
  1967. +  */
  1968. + int
  1969. + pr_menu(ap, usestored)
  1970. +     register char **ap;
  1971. +     int usestored;
  1972. + {
  1973. +     register char **pp;
  1974. +     register i, j;
  1975. +     register int ix;
  1976. +     static int argct;
  1977. +     static int nwidth;
  1978. +     static int dwidth;
  1979. +     static int ncols;
  1980. +     static int nrows;
  1981. +     if (usestored == 0) {
  1982. +         /*
  1983. +          * get dimensions of the list
  1984. +          */
  1985. +         for (argct = 0, nwidth = 0, pp = ap; *pp; argct++, pp++) {
  1986. +             i = strlen(*pp);
  1987. +             nwidth = (i > nwidth) ? i : nwidth;
  1988. +         }
  1989. +         /*
  1990. +          * we will print an index of the form
  1991. +          *    %d)
  1992. +          * in front of each entry
  1993. +          * get the max width of this
  1994. +          */
  1995. +         for (i = argct, dwidth = 1; i >= 10; i /= 10)
  1996. +             dwidth++;
  1997. +         if (argct < COLARGS)
  1998. +             ncols = 1, nrows = argct;
  1999. +         else {
  2000. +             ncols = x_cols/(nwidth+dwidth+3);
  2001. +             nrows = argct/ncols;
  2002. +             if (argct%ncols) nrows++;
  2003. +             if (ncols > nrows)
  2004. +             i = nrows, nrows = ncols, ncols = 1;
  2005. +         }
  2006. +     }
  2007. +     /*
  2008. +      * display the menu
  2009. +      */
  2010. +     for (i = 0; i < nrows; i++) {
  2011. +         for (j = 0; j < ncols; j++) {
  2012. +             ix = j*nrows + i;
  2013. +             if (ix < argct)
  2014. +                 shellf("%*d) %-*.*s ", dwidth, ix+1, nwidth, nwidth, ap[ix]);
  2015. +             }
  2016. +         shellf("\n");
  2017. +     }
  2018. +     return argct;
  2019. + }
  2020. + static int
  2021. + selread()
  2022. + {    char c;
  2023. +     register int    rv;
  2024. +     
  2025. +     switch (read(0, &c, 1)) {
  2026. +        case 1:
  2027. +         rv = c&0xff;
  2028. +         break;
  2029. +        case 0:
  2030. +         rv = EOF;
  2031. +         break;
  2032. +        case -1:
  2033. +         rv = -2;
  2034. +         break;
  2035. +     }
  2036. +     return rv;
  2037. + }
  2038. *** sh/getopts.c.old    Tue May 12 13:42:00 1992
  2039. --- sh/getopts.c    Mon Aug 10 22:02:41 1992
  2040. ***************
  2041. *** 7,13 ****
  2042.    */
  2043.   
  2044.   #ifndef lint
  2045. ! static char *RCSid = "$Id: getopts.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
  2046.   #endif
  2047.   
  2048.   #include "stdh.h"
  2049. --- 7,13 ----
  2050.    */
  2051.   
  2052.   #ifndef lint
  2053. ! static char *RCSid = "$Id: getopts.c,v 1.3 1992/08/10 12:02:41 sjg Exp $";
  2054.   #endif
  2055.   
  2056.   #include "stdh.h"
  2057. ***************
  2058. *** 14,19 ****
  2059. --- 14,24 ----
  2060.   #include <errno.h>
  2061.   #include <setjmp.h>
  2062.   #include "sh.h"
  2063. + #ifdef _BSDI
  2064. + /* internal getopt conflicts with system getopt prototype */
  2065. + # define getopt    local_getopt
  2066. + #endif
  2067.   
  2068.   /*
  2069.    * The following is derived from getopt() source placed into the public
  2070.  
  2071. exit 0 # Just in case...
  2072.