home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / pdksh / patch06a < prev    next >
Encoding:
Text File  |  1992-08-13  |  49.5 KB  |  2,125 lines

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