Annotation of coherent/f/tmp/ksh/ksh4.7.tar, revision 1.1.1.1

1.1       root        1: ./pdksh/  2755    653   1762           0  5302773755   7360 5ustar  hlu./pdksh/README   644    653   1762       11455  5243743631  10316 0ustar  hlu               Public Domain Korn Shell
                      2:                      Version 4.5
                      3: 
                      4: PD KSH:
                      5: 
                      6: This is the latest version of the PD ksh (pdksh).  It is not
                      7: intended to be the ultimate shell but rather a usable ksh work
                      8: alike.  For those of us who have to work on multiple systems it
                      9: is nice to have the same user interface on all.  I resisted
                     10: moving to the ksh on a Bull system at work for nearly a year due
                     11: to the lack of a ksh on my Sun systems.  When I first picked up
                     12: the 3.2 PD KSH a couple of years ago, it took only a few minutes
                     13: to convert a C-shell fan to a ksh fan :-)  Pdksh is not 100%
                     14: compatible with the ksh.  Having said that, I use it daily
                     15: beside a real ksh88 and find them virtually indistinguishable.
                     16: 
                     17: I only run this shell on sun's and only for interactive use.  I
                     18: use it on sun4c, sun3 and sun386 systems.  The shell itself has
                     19: been compiled on each of these both with and without the
                     20: POSIX/ANSI compatability libraries in ./std.  See the file
                     21: MACHINES for details of systems that the shell has been built
                     22: on.
                     23: 
                     24: I have released this version of the shell (with the kind
                     25: permission of the previous maintainers and major contributors) to
                     26: ensure that it is available from usenet archive sites.  Of
                     27: course it remains in the Public Domain.  Equally obviously
                     28: neither myself nor any other contributors make any claims of
                     29: suitability etc.  Ie. NO WARRANTY!!!  If you make any changes
                     30: and distribute them, please leave your own finger prints in the
                     31: source.  Its bad enough being flamed for my own bugs let alone
                     32: anyone elses :-)
                     33: 
                     34: WHATS NEW:
                     35: 
                     36: This update includes Job Control for System V (POSIX), many bug
                     37: fixes and a simple history file mechanism.  See sh/ChangeLog.
                     38: 
                     39: HISTORY:
                     40: 
                     41: This shell was written by Eric Gisin.  It is based on Charles
                     42: Forsyth's public domain V7 shell, which he later contributed to
                     43: Minix.  John R MacMillan picked up Eric Gisin's version after
                     44: Eric moved on to other projects (see ReadMe.jrm).
                     45: 
                     46: Since then there have been many contributors to this shell.
                     47: Most have left their fingerprints within the source and various
                     48: ReadMe.xxx and Changes.xxx files reflect their input.
                     49: 
                     50: This version is basically that known as Eric Gisin's version 3.3
                     51: alpha which I obtained indirectly from John R MacMillan who is
                     52: the most recent maintainer.  This version has much improved
                     53: emacs-mode command line editing (my main contribution) plus
                     54: enough extra emacs-mode features to make it difficult to
                     55: distinguish from ksh88.  Bug fixes from various contributors are
                     56: the only other changes from John MacMillan's version.
                     57: 
                     58: I have upped the version number for this release to distinguish
                     59: it from the original 3.3 version.  This version is much improved
                     60: despite the small number of new features.
                     61: 
                     62: INSTALLATION:
                     63: 
                     64: The file INSTALL contains intructions for building and
                     65: installing the shell.  
                     66: 
                     67: The original instructions indicated that a POSIX compliant
                     68: environment and possibly an ANSI compiler are required.  I have
                     69: used both gcc and native Sun and the GreenHills ANSI compiler
                     70: without problems.
                     71: 
                     72: The POSIX/STDC compatability stuff in ./std seems to cause lots
                     73: of problems for some systems.  This was at least in part because
                     74: I distributed it with half the librraies disabled :-), in any
                     75: case the shell itself in ./sh can now be compiled without any of
                     76: the ./std stuff which makes things much simpler on systems that
                     77: have a real POSIX environment.
                     78: 
                     79: Porting to new environemnts can be a real pain.  I don't really
                     80: plan to make a huge effort in this area since I expect that this
                     81: shell will be mainly required on exotic or obscure systems (the
                     82: ones that the vendor does not provide a ksh for).  Thus the
                     83: small "market" does not warrant a C-news or X11 style
                     84: portability effort.  Of course if people send patches for
                     85: various systems I'm happy to try and integrate them.
                     86: 
                     87: ENVIRONMENT:
                     88: 
                     89: My main interest in this shell is for Sun workstations.  Every
                     90: other UNIX system I use comes with a real ksh.  Being a strictly
                     91: C-shell environment, some improved profile files are in order on
                     92: Sun's.
                     93: 
                     94: The etc directory contains a set of useful environment files.
                     95: These are the same files I use on several systems (many use a
                     96: real ksh):
                     97: ./etc/profile
                     98: ./etc/sys_config.sh
                     99: ./etc/ksh.kshrc        
                    100: 
                    101: The first one is obvious.  The second, sys_config.sh is sourced
                    102: by /etc/profile and several other scripts.  It is used to
                    103: determine the system type so that scripts like profile can be
                    104: used on multiple platforms.
                    105: The third one is also quite useful, add 
                    106: . /etc/ksh.kshrc 
                    107: to user's ~/.kshrc to simplify alias management.
                    108: 
                    109: BUGS:
                    110: 
                    111: Many folk have contributed to this shell.  
                    112: I have attempted to credit (in sh/ChangeLog) the authors of bug
                    113: fixes received since the previous release.
                    114: There are surely still plenty of bugs to be found/fixed.
                    115: 
                    116: There is a template bug report in bug-report [borrowed from the
                    117: X11R5 mit tree], just fill in the blanks and mail to
                    118: [email protected].  
                    119: 
                    120: I hope you find this shell as useful as I do...
                    121: 
                    122: Simon J. Gerraty <[email protected]>
                    123: ./pdksh/etc/  2755    653   1762           0  5302550265  10120 5ustar  hlu./pdksh/etc/profile   644    653   1762       14461  5243743647  11603 0ustar  hlu:
                    124: # NAME:
                    125: #      profile - global initialization for sh,ksh
                    126: #
                    127: # DESCRIPTION:
                    128: #      This file is processed during login by /bin/sh
                    129: #      and /bin/ksh.  It is used to setup the default user
                    130: #      environment.
                    131: #
                    132: # SEE ALSO:
                    133: #      $HOME/.profile
                    134: #      /etc/ksh.kshrc
                    135: 
                    136: # RCSid:
                    137: #      $Id: profile,v 1.4 1992/08/10 12:00:11 sjg Exp $
                    138: #
                    139: #      @(#)Copyright (c) 1991 Simon J. Gerraty
                    140: #
                    141: #      This file is provided in the hope that it will
                    142: #      be of use.  There is absolutely NO WARRANTY.
                    143: #      Permission to copy, redistribute or otherwise
                    144: #      use this file is hereby granted provided that 
                    145: #      the above copyright notice and this notice are
                    146: #      left intact. 
                    147: 
                    148: case "$_INIT_" in
                    149: *env*) ;;
                    150: *)     # do these once
                    151:        _INIT_="$_INIT_"env
                    152:        export _INIT_
                    153:        case `echo -n ""` in
                    154:        -n*)
                    155:          _N_=""; _C_="\c";;
                    156:        *)
                    157:          _N_="-n"; _C_="";;
                    158:        esac
                    159: 
                    160:        if [ -f /unix ]; then
                    161:           # System V
                    162:          [ -z "$TZ" -a -f /etc/TIMEZONE ] && . /etc/TIMEZONE
                    163: 
                    164:          set -- `who -r`
                    165:          case "$3" in
                    166:              S|5|0)    SINGLE=y;;
                    167:              *)        SINGLE=n;;
                    168:          esac
                    169:          # sys_config.sh should set ARCH,OS,C,N,HOSTNAME,uname
                    170:          # we use these in lots of scripts...
                    171:          [ "$SINGLE" = n -a -f /etc/sys_config.sh ] && . /etc/sys_config.sh
                    172:         else
                    173:           [ -f /etc/sys_config.sh ] && . /etc/sys_config.sh
                    174:           SINGLE=n             # doesn't matter so much
                    175:        fi
                    176:        # pick one of the following for the default umask
                    177:        # umask 002     # relaxed       -rwxrwxr-x
                    178:        umask 022       # cautious      -rwxr-xr-x
                    179:        # umask 027     # uptight       -rwxr-x---
                    180:        # umask 077     # paranoid      -rwx------
                    181:        # you can override the default umask
                    182:        # for specific groups later...
                    183: 
                    184:        if [ -d /local ]; then
                    185:                LOCAL=/local
                    186:        else
                    187:                LOCAL=/usr/local
                    188:        fi
                    189: 
                    190:        # set system specific things,
                    191:        # eg. set PATH,MANPATH 
                    192:        # override default ulimit if desired.
                    193:        # defult ulmit is unlimited on SunOS
                    194:        # and 4Mb for most System V
                    195:        case $OS in
                    196:        SunOS)
                    197:                # On sun's /bin -> /usr/bin so leave it out!
                    198:                PATH=/usr/bin:/usr/ucb:/usr/5bin:.
                    199:                MANPATH=/usr/man
                    200:                defterm=vt220
                    201:                ;;
                    202:        SCO-UNIX)
                    203:                PATH=/bin:/usr/bin:/usr/lbin:/usr/dbin:/usr/ldbin:.
                    204:                MANPATH=/usr/man
                    205:                defterm=ansi
                    206:                ;;
                    207:        B.O.S.)
                    208:                PATH=/bin:/usr/bin:.
                    209:                if [ -d /usr/ucb ]; then
                    210:                        PATH=$PATH:/usr/ucb
                    211:                fi
                    212:                MANPATH=/usr/catman
                    213:                defterm=vt220
                    214:                SRC_COMPAT=_SYSV
                    215:                export SRC_COMPAT
                    216:                ;;
                    217:        *)
                    218:                PATH=/bin:/usr/bin:.
                    219:                if [ -d /usr/ucb ]; then
                    220:                        PATH=$PATH:/usr/ucb
                    221:                fi
                    222:                MANPATH=/usr/catman
                    223:                defterm=vt220
                    224:                ;;
                    225:        esac
                    226:        if [ -d ${LOCAL}/bin ]; then
                    227:                PATH=$PATH:${LOCAL}/bin
                    228:        fi
                    229:        case "$HOME" in
                    230:        /)      ;;
                    231:        ""|/tmp)
                    232:                echo "Using /tmp for HOME"
                    233:                HOME=/tmp; export HOME
                    234:                ;;
                    235:        *)
                    236:                if [ -d $HOME/bin ]; then
                    237:                        PATH=$PATH:$HOME/bin
                    238:                fi
                    239:                ;;
                    240:        esac
                    241:        if [ -d ${LOCAL}/man ]; then
                    242:                MANPATH=$MANPATH:${LOCAL}/man
                    243:        fi
                    244:        # make sure these are set at least once
                    245:        LOGNAME=${LOGNAME:-`logname`}
                    246:        USER=${USER:-$LOGNAME}
                    247: 
                    248:        # we expect id to produce output like:
                    249:        # uid=100(sjg) gid=10(staff) groups=10(staff),...
                    250:        S='('
                    251:        E=')'
                    252:        GROUP=`id | cut -d= -f3 | \
                    253:                sed -e "s;^[^${S}][^${S}]*${S}\([^${E}][^${E}]*\)${E}.*$;\1;"`
                    254:        UID=`id | cut -d= -f2 | \
                    255:                 sed -e "s;\([^${S}]*\)${S}.*;\1;"`
                    256:        # set some group specific defaults
                    257:        case "$GROUP" in
                    258:        staff)  # staff deal with things that non-staff 
                    259:                # have no business looking at
                    260:                umask 027
                    261:                ;;
                    262:        extern) # we put external accounts in group "extern"
                    263:                # give them as much privacy as we can...
                    264:                umask 077
                    265:                ulimit 16384    # 8Mb file limit
                    266:                TMOUT=600       # idle timeout
                    267:                ;;
                    268:        esac
                    269: 
                    270:        unset S E GROUP
                    271:        export LOCAL TTY PATH LOGNAME USER
                    272: 
                    273:        if [ -t 1 ]; then
                    274:                # we are interactive
                    275:                TTY=`tty`
                    276:                TTY=`basename $TTY`
                    277:                ORGANIZATION=""
                    278:                COPYRIGHT="Copyright (c) `date +19%y` $ORGANIZATION"
                    279:                export ORGANIZATION COPYRIGHT
                    280: 
                    281:                # set up some env variables
                    282:                MAIL=/usr/spool/mail/$USER
                    283:                MAILPATH=/usr/spool/mail/$USER:/etc/motd
                    284:                EMACSDIR=${LOCAL}/lib/emacs
                    285:                PAGER=${PAGER:-more}
                    286:                export MAIL EMACSDIR MANPATH MAILPATH PAGER
                    287: 
                    288:                CVSROOT=${LOCAL}/src/master
                    289:                EDITOR=emacs
                    290:                FCEDIT=$EDITOR
                    291:                export CVSROOT FCEDIT EDITOR
                    292: #              EMACSLOADPATH=$EMACSDIR/lisp
                    293: #              [ -d $LOCAL/lib/lisp ] && EMACSLOADPATH=$LOCAL/lib/lisp:$EMACSLOADPATH
                    294: #              [ -d $HOME/lisp ] && EMACSLOADPATH=$HOME/lisp:$EMACSLOADPATH
                    295:                case $UID in 
                    296:                0)      PROMPT="<$LOGNAME@$HOSTNAME># ";;
                    297:                *)      PROMPT="<$LOGNAME@$HOSTNAME>$ ";;
                    298:                esac
                    299: #              PUBDIR=/usr/spool/uucppublic
                    300: #              export PUBDIR EMACSLOADPATH
                    301:                [ -f /etc/profile.TeX ] && . /etc/profile.TeX
                    302:        else
                    303:                TTY=none
                    304:        fi
                    305: 
                    306:        # test (and setup if we are Korn shell)
                    307:        if [ "$RANDOM" != "$RANDOM" ]; then
                    308:                # we are Korn shell
                    309:                SHELL=/bin/ksh
                    310:                ENV=${HOME%/}/.kshrc
                    311:                HISTFILE=${HOME%/}/.ksh_hist
                    312:                case $UID in
                    313:                0)
                    314:                        PROMPT="<$LOGNAME@$HOSTNAME:!># ";;
                    315:                *)      PROMPT="<$LOGNAME@$HOSTNAME:!>$ ";;
                    316:                esac
                    317:                export HISTSIZE HISTFILE ENV
                    318:                CDPATH=.:$HOME
                    319:                if [ "$TMOUT" ]; then
                    320:                        typeset -r TMOUT
                    321:                fi
                    322:        else
                    323:                SHELL=/bin/sh
                    324:        fi
                    325:        PS1=$PROMPT
                    326:        export SHELL PS1 EDITOR PATH PROMPT HOSTNAME CDPATH
                    327: ;;
                    328: esac
                    329: 
                    330: # login time initialization
                    331: case "$_INIT_" in
                    332: *log*) ;;
                    333: *)     _INIT_="$_INIT_"log
                    334:        case "$SINGLE" in
                    335:        y)      ;;
                    336:        *)
                    337:        if [ TTY != none -a "$0" != "-su" -a "$LOGNAME" = "`logname`" -a ! -f ~/.hushlogin ]
                    338:        then
                    339:                case $OS in
                    340:                B.O.S.)
                    341:                        case $TTY in
                    342:                        ttyp*)  stty sane       # problems with telnetd
                    343:                                ;;
                    344:                        esac
                    345:                        ;;
                    346:                esac
                    347:                # ensure known state
                    348:                stty isig icanon intr '^c' erase '^h' kill '^u' eof '^d' 
                    349:                mesg y
                    350:                case $TERM in
                    351:                network|unknown|dialup|"") 
                    352:                  echo ${_N_} "Enter terminal type [$defterm]: ${_C_}" 1>&2
                    353:                  read tmpterm
                    354:                  TERM=${tmpterm:-$defterm}
                    355:                  ;;
                    356:                esac
                    357:                # not all of the following are appropriate at all sites
                    358:                # Sun's don't need to cat /etc/motd for instance
                    359:                case "$OS" in
                    360:                SunOS)  ;;
                    361:                SCO-UNIX)       
                    362:                        [ -s /etc/motd ] && cat /etc/motd
                    363:                        [ -x /usr/bin/mail -a -s "$MAIL" ] && 
                    364:                                echo "You have mail."
                    365:                        [ -x /usr/bin/news ] && /usr/bin/news -n
                    366:                        ;;
                    367:                *)
                    368:                        [ -s /etc/motd ] && cat /etc/motd
                    369:                        if [ -x /usr/bin/mailx ]; then
                    370:                          if mailx -e; then
                    371:                            echo "You have mail."
                    372:                            # show the the headers, this might
                    373:                            # be better done in .profile so they
                    374:                            # can override it.
                    375: #                          mailx -H
                    376:                          fi
                    377:                        fi
                    378:                        [ -x /usr/bin/news ] && /usr/bin/news -n
                    379:                        ;;
                    380:                esac
                    381: #              [ -x /usr/games/fortune ] && /usr/games/fortune -a
                    382:                # remind folk who turned on reply.pl to turn it off.
                    383:                if [ -f $HOME/.forward ]; then
                    384:                        echo "Your mail is being forwarded to:"
                    385:                        cat $HOME/.forward
                    386:                        if [ -f $HOME/.recording ]; then
                    387:                                echo "Perhaps you should run \"reply.pl off\""
                    388:                        fi
                    389:                fi
                    390:        fi
                    391:        unset tmpterm defterm C N _C_ _N_
                    392:        esac
                    393:        case "$TERM" in
                    394:        network|unknown|"")     TERM=vt100;;
                    395:        esac
                    396:        export TERM TTY
                    397: ;;
                    398: esac
                    399: # Handle X-terminals if necessary
                    400: [ "$SINGLE" = n -a -f /etc/profile.X11 ] && . /etc/profile.X11
                    401: ./pdksh/etc/ksh.kshrc   644    653   1762        4573  5243743646  12023 0ustar  hlu:
                    402: # NAME:
                    403: #      ksh.kshrc - global initialization for ksh 
                    404: #
                    405: # DESCRIPTION:
                    406: #      Each invocation of /bin/ksh processes the file pointed
                    407: #      to by $ENV (usually $HOME/.kshrc).
                    408: #      This file is intended as a global .kshrc file for the
                    409: #      Korn shell.  A user's $HOME/.kshrc file simply requires
                    410: #      the line:
                    411: #              . /etc/ksh.kshrc
                    412: #      at or near the start to pick up the defaults in this
                    413: #      file which can then be overridden as desired.
                    414: #
                    415: # SEE ALSO:
                    416: #      $HOME/.kshrc
                    417: #
                    418: 
                    419: # RCSid:
                    420: #      $Id: ksh.kshrc,v 1.3 1992/08/10 12:00:08 sjg Exp $
                    421: #
                    422: #      @(#)Copyright (c) 1991 Simon J. Gerraty
                    423: #
                    424: #      This file is provided in the hope that it will
                    425: #      be of use.  There is absolutely NO WARRANTY.
                    426: #      Permission to copy, redistribute or otherwise
                    427: #      use this file is hereby granted provided that 
                    428: #      the above copyright notice and this notice are
                    429: #      left intact. 
                    430: 
                    431: case "$-" in
                    432: *i*)   # we are interactive
                    433:        # we may have su'ed so reset these
                    434:        # NOTE: SCO-UNIX doesn't have whoami,
                    435:        #       install whoami.sh
                    436:        USER=`whoami`
                    437:        PROMPT="<$USER@$HOSTNAME:!>$ "
                    438:        PPROMPT='<$USER@$HOSTNAME:$PWD:!>$ '
                    439:        PS1=$PPROMPT
                    440:        # $TTY is the tty we logged in on,
                    441:        # $tty is that which we are in now (might by pty)
                    442:        tty=`tty`
                    443:        tty=`basename $tty`
                    444: 
                    445:        set -o $EDITOR
                    446: 
                    447:        alias ls='ls -CF'
                    448:        alias h='fc -l | more'
                    449:        # the PD ksh is not 100% compatible
                    450:        case "$KSH_VERSION" in
                    451:        *PD*)   # PD ksh
                    452:                case "$TERM" in
                    453:                xterm*)
                    454:                        # bind arrow keys
                    455:                        bind '^[['=prefix-2
                    456:                        bind '^XA'=up-history
                    457:                        bind '^XB'=down-history
                    458:                        bind '^XC'=forward-char
                    459:                        bind '^XD'=backward-char
                    460:                        ;;
                    461:                esac
                    462:                ;;
                    463:        *)      # real ksh ?
                    464:                ;;
                    465:        esac
                    466:        case "$TERM" in
                    467:        sun*)
                    468:                # these are not as neat as their csh equivalents
                    469:                if [ "$tty" != console ]; then
                    470:                        # ilabel
                    471:                        ILS='\033]L'; ILE='\033\\'
                    472:                        # window title bar
                    473:                        WLS='\033]l'; WLE='\033\\'
                    474:                fi
                    475:                ;;
                    476:        xterm*)
                    477:                ILS='\033]1;'; ILE='\007'
                    478:                WLS='\033]2;xterm: '; WLE='\007'
                    479:                ;;
                    480:        *)      ;;
                    481:        esac
                    482:        # do we want window decorations?
                    483:        if [ "$ILS" ]; then
                    484:                wftp () { ilabel "ftp $*"; "ftp" $*; 
                    485:                        ilabel "$USER@$HOSTNAME"; }
                    486:                wcd () { "cd" $*; eval stripe; }
                    487:                ilabel () { print -n "${ILS}$*${ILE}"; }
                    488:                label () { print -n "${WLS}$*${WLE}"; }
                    489:                alias stripe='label $USER @ $HOSTNAME \($tty\) - $PWD'
                    490:                alias cd=wcd
                    491:                alias ftp=wftp
                    492:                eval stripe
                    493:                eval ilabel "$USER@$HOSTNAME"
                    494:                PS1=$PROMPT
                    495:        fi
                    496:        alias quit=exit
                    497:        alias cls=clear
                    498:        alias logout=exit
                    499:        alias bye=exit
                    500: 
                    501: 
                    502: # add your favourite aliases here
                    503: ;;
                    504: *)     # non-interactive
                    505: ;;
                    506: esac
                    507: # commands for both interactive and non-interactive shells
                    508: ./pdksh/etc/sys_config.sh   644    653   1762        2616  5243743647  12676 0ustar  hlu:
                    509: # NAME:
                    510: #      sys_config.sh - set system specific variables
                    511: #
                    512: # SYNOPSIS:
                    513: #      . /etc/sys_config.sh
                    514: #
                    515: # DESCRIPTION:
                    516: #      Source this script into shell scripts that want to handle
                    517: #      various system types.
                    518: #      You may well want to edit this on a particular system replacing 
                    519: #      `uname -s` etc with the result.  So that the facility will work 
                    520: #      even when in single user mode and uname et al are not available.
                    521: #
                    522: # SEE ALSO:
                    523: #      /etc/profile
                    524: 
                    525: # RCSid:
                    526: #      $Id: sys_config.sh,v 1.2 1992/08/10 12:00:14 sjg Exp $
                    527: #
                    528: #      @(#)Copyright (c) 1991 Simon J. Gerraty
                    529: #
                    530: #      This file is provided in the hope that it will
                    531: #      be of use.  There is absolutely NO WARRANTY.
                    532: #      Permission to copy, redistribute or otherwise
                    533: #      use this file is hereby granted provided that 
                    534: #      the above copyright notice and this notice are
                    535: #      left intact. 
                    536: #
                    537: 
                    538: # determin machine type
                    539: if [ -f /usr/bin/arch ]; then
                    540:        ARCH=`arch`
                    541: elif [ -f /usr/bin/uname -o -f /bin/uname ]; then
                    542:        ARCH=`uname -m`
                    543: fi
                    544: #
                    545: case "$ARCH" in
                    546: sun386)        uname=/usr/5bin/uname
                    547:        OS=SunOS
                    548:        ;;
                    549: *)     uname=uname;;
                    550: esac
                    551: 
                    552: # set the operating system type
                    553: # you can't use `uname -s` with SCO UNIX
                    554: # it returns the same string as `uname -n`
                    555: # so set it manually
                    556: # OS=SCO-UNIX
                    557: # The eval below is a workaround for a bug in the PD ksh.
                    558: OS=${OS:-`eval $uname -s`}
                    559: HOSTNAME=${HOSTNAME:-`eval $uname -n`}
                    560: 
                    561: case `echo -n ""` in
                    562: -n*)   _C_=""; _N_="-n";;
                    563: *)     _C_="\c"; _N_="";;
                    564: esac
                    565: N="${_N_}"
                    566: C="${_C_}"
                    567: export OS ARCH HOSTNAME uname
                    568: ./pdksh/sh/  2755    653   1762           0  5303017545   7757 5ustar  hlu./pdksh/sh/emacs.c   644    653   1762      106051  5243743654  11326 0ustar  hlu/*
                    569:  *  Emacs-like command line editing and history
                    570:  *
                    571:  *  created by Ron Natalie at BRL
                    572:  *  modified by Doug Kingston, Doug Gwyn, and Lou Salkind
                    573:  *  adapted to PD ksh by Eric Gisin
                    574:  */
                    575: 
                    576: #include "config.h"
                    577: #ifdef EMACS
                    578: 
                    579: #ifndef lint
                    580: static char *RCSid = "$Id: emacs.c,v 1.3 1992/08/10 12:02:31 sjg Exp $";
                    581: #endif
                    582: 
                    583: #include "stdh.h"
                    584: #include <signal.h>
                    585: #include <sys/stat.h>
                    586: #include <dirent.h>
                    587: #include <unistd.h>
                    588: #include <fcntl.h>
                    589: #include <ctype.h>
                    590: #include <errno.h>
                    591: #include <setjmp.h>
                    592: #include "sh.h"
                    593: #include "expand.h"
                    594: #include "edit.h"
                    595: 
                    596: #define PUSH_DELETE 1                  /* push all deletes of >1 char */
                    597: 
                    598: static Area    aedit;
                    599: #define        AEDIT   &aedit          /* area for kill ring and macro defns */
                    600: 
                    601: #undef CTRL                    /* _BSD brain damage */
                    602: #define        CTRL(x)         ((x) == '?' ? 0x7F : (x) & 0x1F)        /* ASCII */
                    603: #define        UNCTRL(x)       ((x) == 0x7F ? '?' : (x) | 0x40)        /* ASCII */
                    604: 
                    605: #ifndef S_ISDIR
                    606: #define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
                    607: #endif
                    608: 
                    609: #ifndef S_ISREG
                    610: #define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
                    611: #endif
                    612: 
                    613: /* values returned by keyboard functions */
                    614: #define        KSTD    0
                    615: #define        KPREF   1               /* ^[, ^X */
                    616: #define        KEOL    2               /* ^M, ^J */
                    617: #define        KINTR   3               /* ^G, ^C */
                    618: #define        KNULL   4
                    619:        
                    620: struct x_ftab  {
                    621:        int     (*xf_func)();
                    622:        char    *xf_name;
                    623:        char    xf_db_tab;
                    624:        char    xf_db_char;
                    625:        short   xf_flags;
                    626: };
                    627: 
                    628: #define        XF_ALLOC        2
                    629: #define        XF_NOBIND       4
                    630: 
                    631: #define        iscfs(c)        (c == ' ' || c == '\t') /* Separator for completion */
                    632: #define        ismfs(c)        (!(isalnum(c)|| c == '$'))  /* Separator for motion */
                    633: #define        BEL             0x07
                    634: #define        CMASK           0x7F    /* 7-bit ASCII character mask */
                    635: 
                    636: #define X_TABSZ        128                     /* size of keydef tables etc */
                    637: 
                    638: static int     x_prefix1 = CTRL('['), x_prefix2 = CTRL('X');
                    639: static char   **x_histp;       /* history position */
                    640: static char   **x_nextcmdp;    /* for newline-and-next */
                    641: static char    *xmp;           /* mark pointer */
                    642: static int    (*x_last_command)();
                    643: static struct  x_ftab const *(*x_tab)[X_TABSZ] = NULL; /* key definition */
                    644: static char    *(*x_atab)[X_TABSZ] = NULL; /* macro definitions */
                    645: #define        KILLSIZE        20
                    646: static char    *killstack[KILLSIZE];
                    647: static int     killsp, killtp;
                    648: static int     x_curprefix;
                    649: static char    *macroptr;
                    650: static int     x_maxlen;       /* to determine column width */
                    651: 
                    652: static int      x_insert    ARGS((int c));
                    653: static int      x_ins_string ARGS((int c));
                    654: static void     x_ins       ARGS((char *cp));
                    655: static int      x_del_back  ARGS((int c));
                    656: static int      x_del_char  ARGS((int c));
                    657: static void     x_delete    ARGS((int nc));
                    658: static int      x_del_bword ARGS((int c));
                    659: static int      x_mv_bword  ARGS((int c));
                    660: static int      x_mv_fword  ARGS((int c));
                    661: static int      x_del_fword ARGS((int c));
                    662: static int      x_bword     ARGS((void));
                    663: static int      x_fword     ARGS((void));
                    664: static void     x_goto      ARGS((char *cp));
                    665: static void     x_bs        ARGS((int c));
                    666: static int      x_size_str  ARGS((char *cp));
                    667: static int      x_size      ARGS((int c));
                    668: static void     x_zots      ARGS((char *str));
                    669: static void     x_zotc      ARGS((int c));
                    670: static int      x_mv_back   ARGS((int c));
                    671: static int      x_mv_forw   ARGS((int c));
                    672: static int      x_search_char ARGS((int c));
                    673: static int      x_newline   ARGS((int c));
                    674: static int      x_end_of_text ARGS((int c));
                    675: static int      x_beg_hist  ARGS((int c));
                    676: static int      x_end_hist  ARGS((int c));
                    677: static int      x_prev_com  ARGS((int c));
                    678: static int      x_next_com  ARGS((int c));
                    679: static void     x_load_hist ARGS((char **hp));
                    680: static int      x_nl_next_com ARGS((int c));
                    681: static int      x_eot_del   ARGS((int c));
                    682: static int      x_search_hist ARGS((int c));
                    683: static int      x_search    ARGS((char *pat, int offset));
                    684: static int      x_match     ARGS((char *str, char *pat));
                    685: static int      x_del_line  ARGS((int c));
                    686: static int      x_mv_end    ARGS((int c));
                    687: static int      x_mv_begin  ARGS((int c));
                    688: static int      x_draw_line ARGS((int c));
                    689: static int      x_transpose ARGS((int c));
                    690: static int      x_literal   ARGS((int c));
                    691: static int      x_meta1     ARGS((int c));
                    692: static int      x_meta2     ARGS((int c));
                    693: static int      x_kill      ARGS((int c));
                    694: static void     x_push      ARGS((int nchars));
                    695: static int      x_yank      ARGS((int c));
                    696: static int      x_meta_yank ARGS((int c));
                    697: static int      x_abort     ARGS((int c));
                    698: static int      x_error     ARGS((int c));
                    699: static int      x_stuffreset ARGS((int c));
                    700: static int      x_stuff     ARGS((int c));
                    701: static void     x_mapin     ARGS((char *cp));
                    702: static char *   x_mapout    ARGS((int c));
                    703: static void     x_print     ARGS((int prefix, int key));
                    704: static int      x_set_mark  ARGS((int c));
                    705: static int      x_kill_region ARGS((int c));
                    706: static int      x_xchg_point_mark ARGS((int c));
                    707: static int      x_copy_arg  ARGS((int c));
                    708: static int      x_noop      ARGS((int c));
                    709: #ifdef SILLY
                    710: static int      x_game_of_life ARGS((int c));
                    711: #endif
                    712: static void     add_stash   ARGS((char *dirnam, char *name));
                    713: static void     list_stash  ARGS((void));
                    714: static int      x_comp_comm ARGS((int c));
                    715: static int      x_list_comm ARGS((int c));
                    716: static int      x_complete  ARGS((int c));
                    717: static int      x_enumerate ARGS((int c));
                    718: static int      x_comp_file ARGS((int c));
                    719: static int      x_list_file ARGS((int c));
                    720: static int      x_comp_list ARGS((int c));
                    721: static void     compl_dec   ARGS((int type));
                    722: static void     compl_file  ARGS((int type));
                    723: static void     compl_command ARGS((int type));
                    724: static int      strmatch    ARGS((char *s1, char *s2));
                    725: static int      x_set_arg   ARGS((int c));
                    726: static int      x_prev_histword ARGS((void));
                    727: static int      x_fold_case ARGS((int c));
                    728: 
                    729: static struct x_ftab const x_ftab[] = {
                    730:        {x_insert,      "auto-insert",          0,       0,     0 },
                    731:        {x_error,       "error",                0,       0,     0 },
                    732:        {x_ins_string,  "macro-string",         0,       0,     XF_NOBIND|XF_ALLOC},
                    733:        {x_del_back,    "delete-char-backward", 0, CTRL('H'),   0 },
                    734:        {x_eot_del,     "eot-or-delete",        0, CTRL('D'),   0 },
                    735:        {x_del_bword,   "delete-word-backward", 1, CTRL('H'),   0 },
                    736:        {x_mv_bword,    "backward-word",        1,      'b',    0 },
                    737:        {x_del_line,    "kill-line",            0,      0,      0 },
                    738:        {x_abort,       "abort",                0,      0,      0 },
                    739:        {x_noop,        "no-op",                0,      0,      0 },
                    740: /* Do not move the above! */
                    741:        {x_mv_fword,    "forward-word",         1,      'f',    0 },
                    742:        {x_del_char,    "delete-char-forward",  0,      0,      0 },
                    743:        {x_del_fword,   "delete-word-forward",  1,      'd',    0 },
                    744:        {x_mv_back,     "backward-char",        0, CTRL('B'),   0 },
                    745:        {x_mv_forw,     "forward-char",         0, CTRL('F'),   0 },
                    746:        {x_search_char, "search-character",     0, CTRL(']'),   0 },
                    747:        {x_newline,     "newline",              0, CTRL('M'),   0 },
                    748:        {x_newline,     "newline",              0, CTRL('J'),   0 },
                    749:        {x_end_of_text, "eot",                  0, CTRL('_'),   0 },
                    750:        {x_abort,       "abort",                0, CTRL('G'),   0 },
                    751:        {x_prev_com,    "up-history",           0, CTRL('P'),   0},
                    752:        {x_next_com,    "down-history",         0, CTRL('N'),   0},
                    753:        {x_search_hist, "search-history",       0, CTRL('R'),   0},
                    754:        {x_beg_hist,    "beginning-of-history", 1,      '<',    0},
                    755:        {x_end_hist,    "end-of-history",       1,      '>',    0},
                    756:        {x_mv_end,      "end-of-line",          0, CTRL('E'),   0 },
                    757:        {x_mv_begin,    "beginning-of-line",    0, CTRL('A'),   0 },
                    758:        {x_draw_line,   "redraw",               0, CTRL('L'),   0 },
                    759:        {x_meta1,       "prefix-1",             0, CTRL('['),   0 },
                    760:        {x_meta2,       "prefix-2",             0, CTRL('X'),   0 },
                    761:        {x_kill,        "kill-to-eol",          0, CTRL('K'),   0 },
                    762:        {x_yank,        "yank",                 0, CTRL('Y'),   0 },
                    763:        {x_meta_yank,   "yank-pop",             1,      'y',    0 },
                    764:        {x_literal,     "quote",                0, CTRL('^'),   0 },
                    765:        {x_stuffreset,  "stuff-reset",          0,       0,     0 },
                    766: #if defined(BRL) && defined(TIOCSTI)
                    767:        {x_stuff,       "stuff",                0, CTRL('T'),   0 },
                    768:        {x_transpose,   "transpose-chars",      0,       0,     0 },
                    769: #else
                    770:        {x_stuff,       "stuff",                0,       0,     0 },
                    771:        {x_transpose,   "transpose-chars",      0, CTRL('T'),   0 },
                    772: #endif
                    773: #ifdef COMPLETE_LIST
                    774:        {x_complete,    "complete",             1,      0,      0 },
                    775:        {x_comp_list,   "complete-list",        1, CTRL('['),   0 },
                    776: #else
                    777:        {x_complete,    "complete",             1, CTRL('['),   0 },
                    778:        {x_comp_list,   "complete-list",        1,       0,     0 },
                    779: #endif
                    780:        {x_enumerate,   "list",                 1,      '?',    0 },
                    781:        {x_comp_file,   "complete-file",        1, CTRL('X'),   0 },
                    782:        {x_comp_comm,   "complete-command",     2, CTRL('['),   0 },
                    783:        {x_list_file,   "list-file",            0,       0,     0 },
                    784:        {x_list_comm,   "list-command",         2,      '?',    0 },
                    785:        {x_nl_next_com, "newline-and-next",     0, CTRL('O'),   0 },
                    786:        {x_set_mark,    "set-mark-command",     1,      ' ',    0 },
                    787:        {x_kill_region, "kill-region",          0, CTRL('W'),   0 },
                    788:        {x_xchg_point_mark, "exchange-point-and-mark", 2, CTRL('X'), 0 },
                    789: #if 0
                    790:        {x_copy_arg,    "copy-last-arg",        1,      '_',    0},
                    791: #endif
                    792: #ifdef SILLY
                    793:        {x_game_of_life, "play-game-of-life",   0,      0,      0 },
                    794: #endif 
                    795: #ifdef DEBUG
                    796:         {x_debug_info, "debug-info",           1, CTRL('H'),   0 },
                    797: #endif
                    798:        {x_prev_histword, "prev-hist-word",     1,      '.',    0 },
                    799:        {x_prev_histword, "prev-hist-word",     1,      '_',    0 },
                    800:         {x_set_arg,    "",                     1,      '0',    0 },
                    801:         {x_set_arg,    "",                     1,      '1',    0 },
                    802:         {x_set_arg,    "",                     1,      '2',    0 },
                    803:         {x_set_arg,    "",                     1,      '3',    0 },
                    804:         {x_set_arg,    "",                     1,      '4',    0 },
                    805:         {x_set_arg,    "",                     1,      '5',    0 },
                    806:         {x_set_arg,    "",                     1,      '6',    0 },
                    807:         {x_set_arg,    "",                     1,      '7',    0 },
                    808:         {x_set_arg,    "",                     1,      '8',    0 },
                    809:         {x_set_arg,    "",                     1,      '9',    0 },
                    810:         {x_fold_case,  "upcase-word",          1,      'U',    0 },
                    811:         {x_fold_case,  "downcase-word",        1,      'L',    0 },
                    812:         {x_fold_case,  "capitalize-word",      1,      'C',    0 },
                    813:         {x_fold_case,  "upcase-word",          1,      'u',    0 },
                    814:         {x_fold_case,  "downcase-word",        1,      'l',    0 },
                    815:         {x_fold_case,  "capitalize-word",      1,      'c',    0 },
                    816:        { 0 }
                    817: };
                    818: 
                    819: #define        xft_insert &x_ftab[0]
                    820: #define        xft_error &x_ftab[1]
                    821: #define        xft_ins_string &x_ftab[2]
                    822: #define        xft_erase &x_ftab[3]
                    823: #define        xft_kill &x_ftab[7]
                    824: #define        xft_werase &x_ftab[5]
                    825: #define xft_intr &x_ftab[8]
                    826: #define        xft_quit &x_ftab[9]
                    827: 
                    828: int
                    829: x_emacs(buf, len)
                    830:        char *buf;
                    831:        size_t len;
                    832: {
                    833:        char    c;
                    834:        int     i;
                    835:        int   (*func)();
                    836:        extern  x_insert();
                    837: 
                    838:        xbp = xbuf = buf; xend = buf + len;
                    839:        xlp = xcp = xep = buf;
                    840:        *xcp = 0;
                    841:        xlp_valid = TRUE;
                    842:        xmp = NULL;
                    843:        x_curprefix = 0;
                    844:        macroptr = null;
                    845:        x_histp = histptr + 1;
                    846: 
                    847:        if (x_nextcmdp != NULL) {
                    848:                x_load_hist(x_nextcmdp);
                    849:                x_nextcmdp = NULL;
                    850:        }
                    851: 
                    852:        x_col = promptlen(prompt);
                    853:        x_adj_ok = 1;
                    854:        x_displen = x_cols - 2 - x_col;
                    855:        x_adj_done = 0;
                    856: 
                    857:        while (1)  {
                    858:                x_flush();
                    859:                if (*macroptr)  {
                    860:                        c = *macroptr++;
                    861:                        if (*macroptr == 0)
                    862:                                macroptr = null;
                    863:                }
                    864:                else {
                    865:                        if ((c = x_getc()) < 0)
                    866:                                return i;
                    867:                }
                    868: 
                    869:                if (x_curprefix == -1)
                    870:                        func = x_insert;
                    871:                else
                    872:                        func = x_tab[x_curprefix][c&CMASK]->xf_func;
                    873:                if (func == NULL)
                    874:                        func = x_error;
                    875:                i = c | (x_curprefix << 8);
                    876:                x_curprefix = 0;
                    877:                switch (i = (*func)(i))  {
                    878:                  case KSTD:
                    879:                        x_last_command = func;
                    880:                  case KPREF:
                    881:                  case KNULL:
                    882:                        break;
                    883:                  case KEOL:
                    884:                        i = xep - xbuf;
                    885:                        x_last_command = 0;
                    886:                        return i;
                    887:                  case KINTR:   /* special case for interrupt */
                    888:                        errno = EINTR;
                    889:                        return -1;
                    890:                }
                    891:        }
                    892: }
                    893: 
                    894: static int
                    895: x_insert(c)  {
                    896:        char    str[2];
                    897: 
                    898:        /*
                    899:         *  Should allow tab and control chars.
                    900:         */
                    901:        if (c == 0)  {
                    902:                x_putc(BEL);
                    903:                return KSTD;
                    904:        }
                    905:        str[0] = c;
                    906:        str[1] = 0;
                    907:        x_ins(str);
                    908:        return KSTD;
                    909: }
                    910: 
                    911: static int
                    912: x_ins_string(c)
                    913: {
                    914:        if (*macroptr)   {
                    915:                x_putc(BEL);
                    916:                return KSTD;
                    917:        }
                    918:        macroptr = x_atab[c>>8][c & CMASK];
                    919:        return KSTD;
                    920: }
                    921: 
                    922: static void
                    923: x_ins(cp)
                    924:        char    *cp;
                    925: {
                    926:        int     count;
                    927:        register int    adj = x_adj_done;
                    928: 
                    929:        count = strlen(cp);
                    930:        if (xep+count >= xend) {
                    931:                x_putc(BEL);
                    932:                return;
                    933:        }
                    934: 
                    935:        if (xcp != xep)
                    936:                memmove(xcp+count, xcp, xep - xcp + 1);
                    937:        else
                    938:                xcp[count] = 0;
                    939:        memmove(xcp, cp, count);
                    940:        /*
                    941:         * x_zots() may result in a call to x_adjust()
                    942:         * we want xcp to reflect the new position.
                    943:         */
                    944:        cp = xcp;
                    945:        xcp += count;
                    946:        xep += count;
                    947:        xlp_valid = FALSE;
                    948:        x_lastcp();
                    949:        x_adj_ok = (xcp >= xlp);
                    950:        x_zots(cp);
                    951:        if (adj == x_adj_done)  /* has x_adjust() been called? */
                    952:        {
                    953:          /* no */
                    954:          for (cp = xlp; cp > xcp; )
                    955:            x_bs(*--cp);
                    956:        }
                    957: 
                    958:        x_adj_ok = 1;
                    959:        return;
                    960: }
                    961: 
                    962: static int
                    963: x_del_back(c)  {
                    964:        if (xcp == xbuf)  {
                    965:                x_putc(BEL);
                    966:                return KSTD;
                    967:        }
                    968:        x_goto(xcp - 1);
                    969:        x_delete(1);
                    970:        return KSTD;
                    971: }
                    972: 
                    973: static int
                    974: x_del_char(c)  {
                    975:        if (xcp == xep)  {
                    976:                x_putc(BEL);
                    977:                return KSTD;
                    978:        }
                    979:        x_delete(1);
                    980:        return KSTD;
                    981: }
                    982: 
                    983: static void
                    984: x_delete(nc)
                    985:   int nc;
                    986: {
                    987:        int     i,j;
                    988:        char    *cp;
                    989:        
                    990:        if (nc == 0)
                    991:                return;
                    992:        if (xmp != NULL) {
                    993:                if (xcp + nc > xmp)
                    994:                        xmp = xcp;
                    995:                else if (xmp > xcp)
                    996:                        xmp -= nc;
                    997:        }
                    998: #ifdef PUSH_DELETE
                    999:        /*
                   1000:         * This lets us yank a word we have deleted.
                   1001:         */
                   1002:        if (nc > 1)
                   1003:          x_push(nc);
                   1004: #endif
                   1005:        xep -= nc;
                   1006:        cp = xcp;
                   1007:        j = 0;
                   1008:        i = nc;
                   1009:        while (i--)  {
                   1010:                j += x_size(*cp++);
                   1011:        }
                   1012:        memmove(xcp, xcp+nc, xep - xcp + 1);    /* Copies the null */
                   1013:        x_adj_ok = 0;                   /* don't redraw */
                   1014:        x_zots(xcp);
                   1015:        /*
                   1016:         * if we are already filling the line,
                   1017:         * there is no need to ' ','\b'.
                   1018:         * But if we must, make sure we do the minimum.
                   1019:         */
                   1020:        if ((i = x_cols - 2 - x_col) > 0)
                   1021:        {
                   1022:          j = (j < i) ? j : i;
                   1023:          i = j;
                   1024:          while (i--)
                   1025:            x_putc(' ');
                   1026:          i = j;
                   1027:          while (i--)
                   1028:            x_putc('\b');
                   1029:        }
                   1030:        /*x_goto(xcp);*/
                   1031:        x_adj_ok = 1;
                   1032:        xlp_valid = FALSE;
                   1033:        for (cp = x_lastcp(); cp > xcp; )
                   1034:          x_bs(*--cp);
                   1035: 
                   1036:        return; 
                   1037: }
                   1038: 
                   1039: static int
                   1040: x_del_bword(c)  {
                   1041:        x_delete(x_bword());
                   1042:        return KSTD;
                   1043: }
                   1044: 
                   1045: static int
                   1046: x_mv_bword(c)  {
                   1047:        (void)x_bword();
                   1048:        return KSTD;
                   1049: }
                   1050: 
                   1051: static int
                   1052: x_mv_fword(c)  {
                   1053:        x_goto(xcp + x_fword());
                   1054:        return KSTD;
                   1055: }
                   1056: 
                   1057: static int
                   1058: x_del_fword(c)  {
                   1059:        x_delete(x_fword());
                   1060:        return KSTD;
                   1061: }
                   1062: 
                   1063: static int
                   1064: x_bword()  {
                   1065:        int     nc = 0;
                   1066:        register char *cp = xcp;
                   1067: 
                   1068:        if (cp == xbuf)  {
                   1069:                x_putc(BEL);
                   1070:                return 0;
                   1071:        }
                   1072:        if (x_last_command != x_set_arg)
                   1073:          x_arg = 1;
                   1074:        while (x_arg--)
                   1075:        {
                   1076:          while (cp != xbuf && ismfs(cp[-1]))
                   1077:          {
                   1078:            cp--;
                   1079:            nc++;
                   1080:          }
                   1081:          while (cp != xbuf && !ismfs(cp[-1]))
                   1082:          {
                   1083:            cp--;
                   1084:            nc++;
                   1085:          }
                   1086:        }
                   1087:        x_goto(cp);
                   1088:        return nc;
                   1089: }
                   1090: 
                   1091: static int
                   1092: x_fword()  {
                   1093:        int     nc = 0;
                   1094:        register char   *cp = xcp;
                   1095: 
                   1096:        if (cp == xep)  {
                   1097:                x_putc(BEL);
                   1098:                return 0;
                   1099:        }
                   1100:        if (x_last_command != x_set_arg)
                   1101:          x_arg = 1;
                   1102:        while (x_arg--)
                   1103:        {
                   1104:          while (cp != xep && !ismfs(*cp))
                   1105:          {
                   1106:            cp++;
                   1107:            nc++;
                   1108:          }
                   1109:          while (cp != xep && ismfs(*cp))
                   1110:          {
                   1111:            cp++;
                   1112:            nc++;
                   1113:          }
                   1114:        }
                   1115:        return nc;
                   1116: }
                   1117: 
                   1118: static void
                   1119: x_goto(cp)
                   1120:        register char *cp;
                   1121: {
                   1122:   if (cp < xbp || cp >= (xbp + x_displen))
                   1123:   {
                   1124:     /* we are heading off screen */
                   1125:     xcp = cp;
                   1126:     x_adjust();
                   1127:   }
                   1128:   else
                   1129:   {
                   1130:     if (cp < xcp)              /* move back */
                   1131:     {
                   1132:       while (cp < xcp)
                   1133:        x_bs(*--xcp);
                   1134:     }
                   1135:     else
                   1136:     {
                   1137:       if (cp > xcp)            /* move forward */
                   1138:       {
                   1139:        while (cp > xcp)
                   1140:          x_zotc(*xcp++);
                   1141:       }
                   1142:     }
                   1143:   }
                   1144: }
                   1145: 
                   1146: static void
                   1147: x_bs(c)  {
                   1148:        register i;
                   1149:        i = x_size(c);
                   1150:        while (i--)
                   1151:                x_putc('\b');
                   1152: }
                   1153: 
                   1154: static int
                   1155: x_size_str(cp)
                   1156:        register char *cp;
                   1157: {
                   1158:        register size = 0;
                   1159:        while (*cp)
                   1160:                size += x_size(*cp++);
                   1161:        return size;
                   1162: }
                   1163: 
                   1164: static int
                   1165: x_size(c)  {
                   1166:        if (c=='\t')
                   1167:                return 4;       /* Kludge, tabs are always four spaces. */
                   1168:        if (c < ' ' || c == 0x7F) /* ASCII control char */
                   1169:                return 2;
                   1170:        return 1;
                   1171: }
                   1172: 
                   1173: static void
                   1174: x_zots(str)
                   1175:        register char *str;
                   1176: {
                   1177:   register int adj = x_adj_done;
                   1178: 
                   1179:   x_lastcp();
                   1180:   while (*str && str < xlp && adj == x_adj_done)
                   1181:     x_zotc(*str++);
                   1182: }
                   1183: 
                   1184: static void
                   1185: x_zotc(c)
                   1186:        int c;
                   1187: {
                   1188:        if (c == '\t')  {
                   1189:                /*  Kludge, tabs are always four spaces.  */
                   1190:                x_puts("    ");
                   1191:        } else if (c < ' ' || c == 0x7F)  { /* ASCII */
                   1192:                x_putc('^');
                   1193:                x_putc(UNCTRL(c));
                   1194:        } else
                   1195:                x_putc(c);
                   1196: }
                   1197: 
                   1198: static int
                   1199: x_mv_back(c)  {
                   1200:        if (xcp == xbuf)  {
                   1201:                x_putc(BEL);
                   1202:                return KSTD;
                   1203:        }
                   1204:        x_goto(xcp-1);
                   1205:        return KSTD;
                   1206: }
                   1207: 
                   1208: static int
                   1209: x_mv_forw(c)  {
                   1210:        if (xcp == xep)  {
                   1211:                x_putc(BEL);
                   1212:                return KSTD;
                   1213:        }
                   1214:        x_goto(xcp+1);
                   1215:        return KSTD;
                   1216: }
                   1217: 
                   1218: static int
                   1219: x_search_char(c)
                   1220:        int c;
                   1221: {
                   1222:        char *cp;
                   1223: 
                   1224:        *xep = '\0';
                   1225:        if ((c = x_getc()) < 0 ||
                   1226:            /* we search forward, I don't know what Korn does */
                   1227:            ((cp = (xcp == xep) ? NULL : strchr(xcp+1, c)) == NULL &&
                   1228:            (cp = strchr(xbuf, c)) == NULL)) {
                   1229:                x_putc(BEL);
                   1230:                return KSTD;
                   1231:        }
                   1232:        x_goto(cp);
                   1233:        return KSTD;
                   1234: }
                   1235: 
                   1236: static int
                   1237: x_newline(c)  {
                   1238:        x_putc('\n');
                   1239:        x_flush();
                   1240:        *xep++ = '\n';
                   1241:        return KEOL;
                   1242: }
                   1243: 
                   1244: static int
                   1245: x_end_of_text(c)  {
                   1246: #if 0
                   1247:        x_store_hist();
                   1248: #endif
                   1249:        return KEOL;
                   1250: }
                   1251: 
                   1252: static int x_beg_hist(c) {x_load_hist(history); return KSTD;}
                   1253: 
                   1254: static int x_end_hist(c) {x_load_hist(histptr); return KSTD;}
                   1255: 
                   1256: static int x_prev_com(c) {x_load_hist(x_histp-1); return KSTD;}
                   1257: 
                   1258: static int x_next_com(c) {x_load_hist(x_histp+1); return KSTD;}
                   1259: 
                   1260: static void
                   1261: x_load_hist(hp)
                   1262:        register char **hp;
                   1263: {
                   1264:        int     oldsize;
                   1265: 
                   1266:        if (hp < history || hp > histptr) {
                   1267:                x_putc(BEL);
                   1268:                return;
                   1269:        }
                   1270:        x_histp = hp;
                   1271:        oldsize = x_size_str(xbuf);
                   1272:        (void)strcpy(xbuf, *hp);
                   1273:        xbp = xbuf;
                   1274:        xep = xcp = xbuf + strlen(*hp);
                   1275:        xlp_valid = FALSE;
                   1276:        if (xep > x_lastcp())
                   1277:          x_goto(xep);
                   1278:        else
                   1279:          x_redraw(oldsize);
                   1280: }
                   1281: 
                   1282: static int
                   1283: x_nl_next_com(c)
                   1284: int    c;
                   1285: {
                   1286:        x_nextcmdp = x_histp + 1;
                   1287:        return (x_newline(c));
                   1288: }
                   1289: 
                   1290: static int
                   1291: x_eot_del(c)
                   1292: int    c;
                   1293: {
                   1294:        if (xep == xbuf)
                   1295:                return (x_end_of_text(c));
                   1296:        else
                   1297:                return (x_del_char(c));
                   1298: }
                   1299: 
                   1300: static int x_search(), x_match();
                   1301: 
                   1302: /* reverse incremental history search */
                   1303: static int
                   1304: x_search_hist(c)
                   1305:        int c;
                   1306: {
                   1307:        int offset = -1;        /* offset of match in xbuf, else -1 */
                   1308:        char pat [256+1];       /* pattern buffer */
                   1309:        register char *p = pat;
                   1310:        int (*func)();
                   1311: 
                   1312:        *p = 0;
                   1313:        while (1) {
                   1314:                if (offset < 0) {
                   1315:                        x_puts("\nI-search: ");
                   1316:                        x_zots(pat);
                   1317:                }
                   1318:                x_flush();
                   1319:                if ((c = x_getc()) < 0)
                   1320:                        return KSTD;
                   1321:                func = x_tab[0][c&CMASK]->xf_func;
                   1322:                if (c == CTRL('['))
                   1323:                        break;
                   1324:                else if (func == x_search_hist)
                   1325:                        offset = x_search(pat, offset);
                   1326:                else if (func == x_del_back)
                   1327:                        continue;       /* todo */
                   1328:                else if (func == x_insert) {
                   1329:                        /* add char to pattern */
                   1330:                        *p++ = c, *p = 0;
                   1331:                        if (offset >= 0) {
                   1332:                                /* already have partial match */
                   1333:                                offset = x_match(xbuf, pat);
                   1334:                                if (offset >= 0) {
                   1335:                                        x_goto(xbuf + offset + (p - pat) - (*pat == '^'));
                   1336:                                        continue;
                   1337:                                }
                   1338:                        }
                   1339:                        offset = x_search(pat, offset);
                   1340:                } else { /* other command */
                   1341:                        static char push[2];
                   1342:                        push[0] = c;
                   1343:                        macroptr = push; /* push command */
                   1344:                        break;
                   1345:                }
                   1346:        }
                   1347:        if (offset < 0)
                   1348:                x_redraw(-1);
                   1349:        return KSTD;
                   1350: }
                   1351: 
                   1352: /* search backward from current line */
                   1353: static int
                   1354: x_search(pat, offset)
                   1355:        char *pat;
                   1356:        int offset;
                   1357: {
                   1358:        register char **hp;
                   1359:        int i;
                   1360: 
                   1361:        for (hp = x_histp; --hp >= history; ) {
                   1362:                i = x_match(*hp, pat);
                   1363:                if (i >= 0) {
                   1364:                        if (offset < 0)
                   1365:                                x_putc('\n');
                   1366:                        x_load_hist(hp);
                   1367:                        x_goto(xbuf + i + strlen(pat) - (*pat == '^'));
                   1368:                        return i;
                   1369:                }
                   1370:        }
                   1371:        x_putc(BEL);
                   1372:        x_histp = histptr;
                   1373:        return -1;
                   1374: }
                   1375: 
                   1376: /* return position of first match of pattern in string, else -1 */
                   1377: static int
                   1378: x_match(str, pat)
                   1379:        char *str, *pat;
                   1380: {
                   1381:        if (*pat == '^') {
                   1382:                return (strncmp(str, pat+1, strlen(pat+1)) == 0) ? 0 : -1;
                   1383:        } else {
                   1384:                char *q = strstr(str, pat);
                   1385:                return (q == NULL) ? -1 : q - str;
                   1386:        }
                   1387: }
                   1388: 
                   1389: static int
                   1390: x_del_line(c)  {
                   1391:        int     i, j;
                   1392: 
                   1393:        *xep = 0;
                   1394:        i = xep- xbuf;
                   1395:        j = x_size_str(xbuf);
                   1396:        xcp = xbuf;
                   1397:        x_push(i);
                   1398:        xlp = xbp = xep = xbuf;
                   1399:        xlp_valid = TRUE;
                   1400:        *xcp = 0;
                   1401:        xmp = NULL;
                   1402:        x_redraw(j);
                   1403:        return KSTD;
                   1404: }
                   1405: 
                   1406: static int
                   1407: x_mv_end(c)  {
                   1408:        x_goto(xep);
                   1409:        return KSTD;
                   1410: }
                   1411: 
                   1412: static int
                   1413: x_mv_begin(c)  {
                   1414:        x_goto(xbuf);
                   1415:        return KSTD;
                   1416: }
                   1417: 
                   1418: static int
                   1419: x_draw_line(c)
                   1420: {
                   1421:        x_redraw(-1);
                   1422:        return KSTD;
                   1423: 
                   1424: }
                   1425: 
                   1426: void
                   1427: x_redraw(limit)
                   1428:   int limit;
                   1429: {
                   1430:        int     i, j;
                   1431:        char    *cp;
                   1432:        
                   1433:        x_adj_ok = 0;
                   1434:        if (limit == -1)
                   1435:                x_putc('\n');
                   1436:        else 
                   1437:                x_putc('\r');
                   1438:        x_flush();
                   1439:        if (xbp == xbuf)
                   1440:        {
                   1441:          pprompt(prompt);
                   1442:          x_col = promptlen(prompt);
                   1443:        }
                   1444:        x_displen = x_cols - 2 - x_col;
                   1445:        xlp_valid = FALSE;
                   1446:        cp = x_lastcp();
                   1447:        x_zots(xbp);
                   1448:        if (xbp != xbuf || xep > xlp)
                   1449:          limit = x_cols;
                   1450:        if (limit >= 0)
                   1451:        {
                   1452:          if (xep > xlp)
                   1453:            i = 0;                      /* we fill the line */
                   1454:          else
                   1455:            i = limit - (xlp - xbp);
                   1456: 
                   1457:          for (j = 0; j < i && x_col < (x_cols - 2); j++)
                   1458:            x_putc(' ');
                   1459:          i = ' ';
                   1460:          if (xep > xlp)                /* more off screen */
                   1461:          {
                   1462:            if (xbp > xbuf)
                   1463:              i = '*';
                   1464:            else
                   1465:              i = '>';
                   1466:          }
                   1467:          else
                   1468:            if (xbp > xbuf)
                   1469:              i = '<';
                   1470:          x_putc(i);
                   1471:          j++;
                   1472:          while (j--)
                   1473:            x_putc('\b');
                   1474:        }
                   1475:        for (cp = xlp; cp > xcp; )
                   1476:          x_bs(*--cp);
                   1477:        x_adj_ok = 1;
                   1478:        _D_(x_flush();)
                   1479:        return;
                   1480: }
                   1481: 
                   1482: static int
                   1483: x_transpose(c)  {
                   1484:        char    tmp;
                   1485:        if (xcp == xbuf) {
                   1486:                x_putc(BEL);
                   1487:                return KSTD;
                   1488:        } else if (xcp == xep) {
                   1489:                if (xcp - xbuf == 1) {
                   1490:                        x_putc(BEL);
                   1491:                        return KSTD;
                   1492:                }
                   1493:                x_bs(xcp[-1]);
                   1494:                x_bs(xcp[-2]);
                   1495:                x_zotc(xcp[-1]);
                   1496:                x_zotc(xcp[-2]);
                   1497:                tmp = xcp[-1];
                   1498:                xcp[-1] = xcp[-2];
                   1499:                xcp[-2] = tmp;
                   1500:        } else {
                   1501:                x_bs(xcp[-1]);
                   1502:                x_zotc(xcp[0]);
                   1503:                x_zotc(xcp[-1]);
                   1504:                tmp = xcp[-1];
                   1505:                xcp[-1] = xcp[0];
                   1506:                xcp[0] = tmp;
                   1507:                x_bs(xcp[0]);
                   1508:        }
                   1509:        return KSTD;
                   1510: }
                   1511: 
                   1512: static int
                   1513: x_literal(c)  {
                   1514:        x_curprefix = -1;
                   1515:        return KSTD;
                   1516: }
                   1517: 
                   1518: static int
                   1519: x_meta1(c)  {
                   1520:        x_curprefix = 1;
                   1521:        return KPREF;
                   1522: }
                   1523: 
                   1524: static int
                   1525: x_meta2(c)  {
                   1526:        x_curprefix = 2;
                   1527:        return KPREF;
                   1528: }
                   1529: 
                   1530: static int
                   1531: x_kill(c)  {
                   1532:        int     i;
                   1533: 
                   1534:        i = xep - xcp;
                   1535:        xlp = xcp;
                   1536:        xlp_valid = TRUE;
                   1537:        x_push(i);
                   1538:        x_delete(i);
                   1539:        return KSTD;
                   1540: }
                   1541: 
                   1542: static void
                   1543: x_push(nchars)  {
                   1544:        char    *cp;
                   1545:        cp = alloc((size_t)(nchars+1), AEDIT);
                   1546:        memmove(cp, xcp, nchars);
                   1547:        cp[nchars] = 0;
                   1548:        if (killstack[killsp])
                   1549:                afree((void *)killstack[killsp], AEDIT);
                   1550:        killstack[killsp] = cp;
                   1551:        killsp = (killsp + 1) % KILLSIZE;
                   1552: }
                   1553: 
                   1554: static int
                   1555: x_yank(c)  {
                   1556:        if (killsp == 0)
                   1557:                killtp = KILLSIZE;
                   1558:        else
                   1559:                killtp = killsp;
                   1560:        killtp --;
                   1561:        if (killstack[killtp] == 0)  {
                   1562:                x_puts("\nnothing to yank");
                   1563:                x_redraw(-1);
                   1564:                return KSTD;
                   1565:        }
                   1566:        xmp = xcp;
                   1567:        x_ins(killstack[killtp]);
                   1568:        return KSTD;
                   1569: }
                   1570: 
                   1571: static int
                   1572: x_meta_yank(c)  {
                   1573:        int     len;
                   1574:        if (x_last_command != x_yank && x_last_command != x_meta_yank)  {
                   1575:                x_puts("\nyank something first");
                   1576:                x_redraw(-1);
                   1577:                return KSTD;
                   1578:        }
                   1579:        len = strlen(killstack[killtp]);
                   1580:        x_goto(xcp - len);
                   1581:        x_delete(len);
                   1582:        do  {
                   1583:                if (killtp == 0)
                   1584:                        killtp = KILLSIZE - 1;
                   1585:                else
                   1586:                        killtp--;
                   1587:        }  while (killstack[killtp] == 0);
                   1588:        x_ins(killstack[killtp]);
                   1589:        return KSTD;
                   1590: }
                   1591: 
                   1592: static int
                   1593: x_abort(c) {
                   1594:        /* x_zotc(c); */
                   1595:        xlp = xep = xcp = xbp = xbuf;
                   1596:        xlp_valid = TRUE;
                   1597:        *xcp = 0;
                   1598:        return KINTR;
                   1599: }
                   1600: 
                   1601: static int
                   1602: x_error(c) {
                   1603:        x_putc(BEL);
                   1604:        return KSTD;
                   1605: }
                   1606: 
                   1607: static int
                   1608: x_stuffreset(c)
                   1609: {
                   1610: #ifdef TIOCSTI
                   1611:        (void)x_stuff(c);
                   1612:        return KINTR;
                   1613: #else
                   1614:        x_zotc(c);
                   1615:        xlp = xcp = xep = xbp = xbuf;
                   1616:        xlp_valid = TRUE;
                   1617:        *xcp = 0;
                   1618:        x_redraw(-1);
                   1619:        return KSTD;
                   1620: #endif
                   1621: }
                   1622: 
                   1623: static int
                   1624: x_stuff(c)
                   1625: {
                   1626: #if 0 || defined TIOCSTI
                   1627:        char    ch = c;
                   1628:        bool_t  savmode = x_mode(FALSE);
                   1629: 
                   1630:        (void)ioctl(ttyfd, TIOCSTI, &ch);
                   1631:        (void)x_mode(savmode);
                   1632:        x_redraw(-1);
                   1633: #endif
                   1634:        return KSTD;
                   1635: }
                   1636: 
                   1637: static void
                   1638: x_mapin(cp)
                   1639:        char    *cp;
                   1640: {
                   1641:        char    *op;
                   1642: 
                   1643:        op = cp;
                   1644:        while (*cp)  {
                   1645:                /* XXX -- should handle \^ escape? */
                   1646:                if (*cp == '^')  {
                   1647:                        cp++;
                   1648:                        if (*cp >= '?') /* includes '?'; ASCII */
                   1649:                                *op++ = CTRL(*cp);
                   1650:                        else  {
                   1651:                                *op++ = '^';
                   1652:                                cp--;
                   1653:                        }
                   1654:                } else
                   1655:                        *op++ = *cp;
                   1656:                cp++;
                   1657:        }
                   1658:        *op = 0;
                   1659: }
                   1660: 
                   1661: static char *
                   1662: x_mapout(c)
                   1663:        int c;
                   1664: {
                   1665:        static char buf[8];
                   1666:        register char *p = buf;
                   1667: 
                   1668:        if (c < ' ' || c == 0x7F)  { /* ASCII */
                   1669:                *p++ = '^';
                   1670:                *p++ = (c == 0x7F) ? '?' : (c | 0x40);
                   1671:        } else
                   1672:                *p++ = c;
                   1673:        *p = 0;
                   1674:        return buf;
                   1675: }
                   1676: 
                   1677: static void
                   1678: x_print(prefix, key)
                   1679:        int prefix, key;
                   1680: {
                   1681:        if (prefix == 1)
                   1682:                shellf("%s", x_mapout(x_prefix1));
                   1683:        if (prefix == 2)
                   1684:                shellf("%s", x_mapout(x_prefix2));
                   1685:        shellf("%s = ", x_mapout(key));
                   1686:        if (x_tab[prefix][key]->xf_func != x_ins_string)
                   1687:                shellf("%s\n", x_tab[prefix][key]->xf_name);
                   1688:        else
                   1689:                shellf("'%s'\n", x_atab[prefix][key]);
                   1690: }
                   1691: 
                   1692: void
                   1693: x_bind(a1, a2, macro)
                   1694:        char *a1, *a2;
                   1695:        int macro;              /* bind -m */
                   1696: {
                   1697:        struct x_ftab const *fp;
                   1698:        int prefix, key;
                   1699:        char *sp = NULL;
                   1700: 
                   1701:        if (x_tab == NULL)
                   1702:                errorf("cannot bind, not a tty\n");
                   1703: 
                   1704:        if (a1 == NULL) {
                   1705:                for (prefix = 0; prefix < 3; prefix++)
                   1706:                    for (key = 0; key < 0x80; key++) {
                   1707:                        fp = x_tab[prefix][key];
                   1708:                        if (fp == NULL ||
                   1709:                            fp->xf_func == x_insert || fp->xf_func == x_error)
                   1710:                                continue;
                   1711:                        x_print(prefix, key);
                   1712:                    }
                   1713:                return;
                   1714:        }
                   1715: 
                   1716:        x_mapin(a1);
                   1717:        prefix = key = 0;
                   1718:        for (;; a1++) {
                   1719:                key = *a1;
                   1720:                if (x_tab[prefix][key]->xf_func == x_meta1)
                   1721:                        prefix = 1;
                   1722:                else
                   1723:                if (x_tab[prefix][key]->xf_func == x_meta2)
                   1724:                        prefix = 2;
                   1725:                else
                   1726:                        break;
                   1727:        }
                   1728: 
                   1729:        if (a2 == NULL) {
                   1730:                x_print(prefix, key);
                   1731:                return;
                   1732:        }
                   1733: 
                   1734:        if (*a2 == 0)
                   1735:                fp = xft_insert;
                   1736:        else if (!macro) {
                   1737:                for (fp = x_ftab; fp->xf_func; fp++)
                   1738:                        if (strcmp(fp->xf_name, a2) == 0)
                   1739:                                break;
                   1740:                if (fp->xf_func == NULL || (fp->xf_flags & XF_NOBIND))
                   1741:                        errorf("%s: no such function\n", a2);
                   1742:                if (fp->xf_func == x_meta1)
                   1743:                        x_prefix1 = key;
                   1744:                if (fp->xf_func == x_meta2)
                   1745:                        x_prefix2 = key;
                   1746:        } else {
                   1747:                fp = xft_ins_string;
                   1748:                x_mapin(a2);
                   1749:                sp = strsave(a2, AEDIT);
                   1750:        }
                   1751: 
                   1752:        if ((x_tab[prefix][key]->xf_flags & XF_ALLOC) && x_atab[prefix][key])
                   1753:                afree((void *)x_atab[prefix][key], AEDIT);
                   1754:        x_tab[prefix][key] = fp;
                   1755:        x_atab[prefix][key] = sp;
                   1756: }
                   1757: 
                   1758: void
                   1759: x_init_emacs()
                   1760: {
                   1761:        register int i, j;
                   1762:        struct x_ftab const *fp;
                   1763: 
                   1764:        ainit(AEDIT);
                   1765: 
                   1766:        x_tab = (struct x_ftab *(*)[X_TABSZ]) alloc(sizeofN(*x_tab, 3), AEDIT);
                   1767:        for (j = 0; j < 128; j++)
                   1768:                x_tab[0][j] = xft_insert;
                   1769:        for (i = 1; i < 3; i++)
                   1770:                for (j = 0; j < 128; j++)
                   1771:                        x_tab[i][j] = xft_error;
                   1772:        for (fp = x_ftab; fp->xf_func; fp++)
                   1773:                if (fp->xf_db_char || fp->xf_db_tab)
                   1774:                        x_tab[fp->xf_db_tab][fp->xf_db_char] = fp;
                   1775: 
                   1776:        x_atab = (char *(*)[X_TABSZ]) alloc(sizeofN(*x_atab, 3), AEDIT);
                   1777:        for (i = 1; i < 3; i++)
                   1778:                for (j = 0; j < 128; j++)
                   1779:                        x_atab[i][j] = NULL;
                   1780: }
                   1781: 
                   1782: void
                   1783: x_emacs_keys(erase, kill, werase, intr, quit)
                   1784:        int erase, kill, werase, intr, quit;
                   1785: {
                   1786:        x_tab[0][erase] = xft_erase;
                   1787:        x_tab[0][kill] = xft_kill;
                   1788:        x_tab[0][werase] = xft_werase;
                   1789:        x_tab[0][intr] = xft_intr;
                   1790:        x_tab[0][quit] = xft_quit;
                   1791:        x_tab[1][erase] = xft_werase;
                   1792: }
                   1793: 
                   1794: static int
                   1795: x_set_mark(c) {
                   1796:        xmp = xcp;
                   1797:        return KSTD;
                   1798: }
                   1799: 
                   1800: static int
                   1801: x_kill_region(c) {
                   1802:        int     rsize;
                   1803:        char    *xr;
                   1804: 
                   1805:        if (xmp == NULL) {
                   1806:                x_putc(BEL);
                   1807:                return KSTD;
                   1808:        }
                   1809:        if (xmp > xcp) {
                   1810:                rsize = xmp - xcp;
                   1811:                xr = xcp;
                   1812:        } else {
                   1813:                rsize = xcp - xmp;
                   1814:                xr = xmp;
                   1815:        }
                   1816:        x_goto(xr);
                   1817:        x_push(rsize);
                   1818:        x_delete(rsize);
                   1819:        xmp = xr;
                   1820:        return KSTD;
                   1821: }
                   1822: 
                   1823: static int
                   1824: x_xchg_point_mark(c) {
                   1825:        char    *tmp;
                   1826: 
                   1827:        if (xmp == NULL) {
                   1828:                x_putc(BEL);
                   1829:                return KSTD;
                   1830:        }
                   1831:        tmp = xmp;
                   1832:        xmp = xcp;
                   1833:        x_goto( tmp );
                   1834:        return KSTD;
                   1835: }
                   1836: 
                   1837: #if 0
                   1838: static int
                   1839: x_copy_arg(c)  {
                   1840:        char *last;
                   1841:        if ((last = strval(local("_"))) && *last)
                   1842:                x_ins(last);
                   1843:        return KSTD;
                   1844: }
                   1845: #endif
                   1846: 
                   1847: static int
                   1848: x_noop(c) {
                   1849:        return KNULL;
                   1850: }
                   1851: 
                   1852: #ifdef SILLY
                   1853: static int
                   1854: x_game_of_life(c)  {
                   1855:        char    newbuf [256+1];
                   1856:        register char *ip, *op;
                   1857:        int     i, len;
                   1858: 
                   1859:        i = xep - xbuf;
                   1860:        *xep = 0;
                   1861:        len = x_size_str(xbuf);
                   1862:        xcp = xbp = xbuf;
                   1863:        memmove(newbuf+1, xbuf, i);
                   1864:        newbuf[0] = 'A';
                   1865:        newbuf[i] = 'A';
                   1866:        for (ip = newbuf+1, op = xbuf; --i >= 0; ip++, op++)  {
                   1867:                /*  Empty space  */
                   1868:                if (*ip < '@' || *ip == '_' || *ip == 0x7F)  {
                   1869:                        /*  Two adults, make whoopee */
                   1870:                        if (ip[-1] < '_' && ip[1] < '_')  {
                   1871:                                /*  Make kid look like parents.  */
                   1872:                                *op = '`' + ((ip[-1] + ip[1])/2)%32;
                   1873:                                if (*op == 0x7F) /* Birth defect */
                   1874:                                        *op = '`';
                   1875:                        }
                   1876:                        else
                   1877:                                *op = ' ';      /* nothing happens */
                   1878:                        continue;
                   1879:                }
                   1880:                /*  Child */
                   1881:                if (*ip > '`')  {
                   1882:                        /*  All alone, dies  */
                   1883:                        if (ip[-1] == ' ' && ip[1] == ' ')
                   1884:                                *op = ' ';
                   1885:                        else    /*  Gets older */
                   1886:                                *op = *ip-'`'+'@';
                   1887:                        continue;
                   1888:                }
                   1889:                /*  Adult  */
                   1890:                /*  Overcrowded, dies */
                   1891:                if (ip[-1] >= '@' && ip[1] >= '@')  {
                   1892:                        *op = ' ';
                   1893:                        continue;
                   1894:                }
                   1895:                *op = *ip;
                   1896:        }
                   1897:        *op = 0;
                   1898:        x_redraw(len);
                   1899:        return KSTD;
                   1900: }
                   1901: #endif
                   1902: 
                   1903: /*
                   1904:  *     File/command name completion routines
                   1905:  */
                   1906: 
                   1907: /* type: 0 for list, 1 for completion */
                   1908: 
                   1909: static XPtrV words;
                   1910: 
                   1911: static void
                   1912: add_stash(dirnam, name)
                   1913:        char *dirnam;   /* directory name, if file */
                   1914:        char *name;
                   1915: {
                   1916:        char *cp;
                   1917:        register int type = 0;  /* '*' if executable, '/' if directory, else 0 */
                   1918:        register int len = strlen(name);
                   1919: 
                   1920:        /* determine file type */
                   1921:        if (dirnam)  {
                   1922:                struct stat statb;
                   1923:                char *buf = alloc((size_t)(strlen(dirnam)+len+2), ATEMP);
                   1924: 
                   1925:                if (strcmp(dirnam, ".") == 0)
                   1926:                        *buf = '\0';
                   1927:                else if (strcmp(dirnam, "/") == 0)
                   1928:                        (void)strcpy(buf, "/");
                   1929:                else
                   1930:                        (void)strcat(strcpy(buf, dirnam), "/");
                   1931:                (void)strcat(buf, name);
                   1932:                if (stat(buf, &statb)==0)
                   1933:                        if (S_ISDIR(statb.st_mode))
                   1934:                                type = '/';
                   1935:                        else if (S_ISREG(statb.st_mode) && access(buf, 01)==0)
                   1936:                                type = '*';
                   1937:                if (type)
                   1938:                        ++len;
                   1939:                afree((void *)buf, ATEMP);
                   1940:        }
                   1941: 
                   1942:        if (len > x_maxlen)
                   1943:                x_maxlen = len;
                   1944: 
                   1945:        /* stash name for later sorting */
                   1946:        cp = alloc((size_t)(len+1), ATEMP);
                   1947:        (void)strcpy(cp = alloc((size_t)(len+1), ATEMP), name);
                   1948:        if (dirnam && type)  {  /* append file type indicator */
                   1949:                cp[len-1] = type;
                   1950:                cp[len] = '\0';
                   1951:        }
                   1952:        XPput(words, cp);
                   1953: }
                   1954: 
                   1955: static void
                   1956: list_stash()
                   1957: {
                   1958:        register char **array, **record;
                   1959:        int items = 0, tabstop, loc, nrows, jump, offset;
                   1960: 
                   1961:        items = XPsize(words);
                   1962:        array = (char**) XPptrv(words);
                   1963:        if (items == 0)
                   1964:                return;
                   1965:        qsortp(XPptrv(words), (size_t)XPsize(words), xstrcmp);
                   1966: 
                   1967:        /* print names */
                   1968:        x_maxlen = (x_maxlen/8 + 1) * 8;        /* column width */
                   1969:        nrows = (items-1) / (x_cols/x_maxlen) + 1;
                   1970:        for (offset = 0; offset < nrows; ++offset)  {
                   1971:                tabstop = loc = 0;
                   1972:                x_putc('\n');
                   1973:                for (jump = 0; offset+jump < items; jump += nrows)  {
                   1974:                        if (jump)
                   1975:                                while (loc < tabstop)  {
                   1976:                                        x_putc('\t');
                   1977:                                        loc = (loc/8 + 1) * 8;
                   1978:                                }
                   1979:                        record = array + (offset + jump);
                   1980:                        x_puts(*record);
                   1981:                        loc += strlen(*record);
                   1982:                        tabstop += x_maxlen;    /* next tab stop */
                   1983:                        afree((void *)*record, ATEMP);
                   1984:                }
                   1985:        }
                   1986: 
                   1987:        afree((void*)array, ATEMP);
                   1988:        x_redraw(-1);
                   1989: }
                   1990: 
                   1991: static int
                   1992: x_comp_comm(c)  {
                   1993:        compl_command(1);
                   1994:        return KSTD;
                   1995: }
                   1996: static int
                   1997: x_list_comm(c)  {
                   1998:        compl_command(0);
                   1999:        return KSTD;
                   2000: }
                   2001: static int
                   2002: x_complete(c)  {
                   2003:        compl_dec(1);
                   2004:        return KSTD;
                   2005: }
                   2006: static int
                   2007: x_enumerate(c)  {
                   2008:        compl_dec(0);
                   2009:        return KSTD;
                   2010: }
                   2011: static int
                   2012: x_comp_file(c)   {
                   2013:        compl_file(1);
                   2014:        return KSTD;
                   2015: }
                   2016: static int
                   2017: x_list_file(c)  {
                   2018:        compl_file(0);
                   2019:        return KSTD;
                   2020: }
                   2021: static int
                   2022: x_comp_list(c)   {
                   2023:        compl_dec(2);
                   2024:        return KSTD;
                   2025: }
                   2026: 
                   2027: static void compl_dec(type) {  char    *cp;    cp = xcp; 
                   2028:        while (cp != xbuf && !iscfs(*cp))
                   2029:                cp--;
                   2030:        if (cp == xbuf && strchr(cp, '/') == NULL)
                   2031:                compl_command(type);
                   2032:        else
                   2033:                compl_file(type);
                   2034: }
                   2035: 
                   2036: static void
                   2037: compl_file(type)
                   2038: {
                   2039:        char    *str;
                   2040:        register char *cp, *xp;
                   2041:        char    *lastp;
                   2042:        char    *dirnam;
                   2043:        char    buf [256+1];
                   2044:        char    bug [256+1];
                   2045:        DIR    *dirp;
                   2046:        struct dirent *dp;
                   2047:        long    loc = -1;
                   2048:        int     len;
                   2049:        int     multi = 0;
                   2050: 
                   2051:        /* type == 0 for list, 1 for complete and 2 for complete-list */
                   2052:        str = xcp;
                   2053:        cp = buf;
                   2054:        xp = str;
                   2055:        while (xp != xbuf)  {
                   2056:                --xp;
                   2057:                if (iscfs(*xp))  {
                   2058:                        xp++;
                   2059:                        break;
                   2060:                }
                   2061:        }
                   2062:        if (digit(*xp) && (xp[1] == '<' || xp[1] == '>'))
                   2063:                xp++;
                   2064:        while (*xp == '<' || *xp == '>')
                   2065:                xp++;
                   2066:        if (type) {                     /* for complete */
                   2067:                while (*xcp && !iscfs(*xcp))
                   2068:                        x_zotc(*xcp++);
                   2069:        }
                   2070:        if (type != 1) {                /* for list */
                   2071:                x_maxlen = 0;
                   2072:                XPinit(words, 16);
                   2073:        }
                   2074:        while (*xp && !iscfs(*xp))
                   2075:                *cp++ = *xp++;
                   2076: 
                   2077:        *cp = 0;
                   2078:        strcpy(buf, cp = substitute(buf, DOTILDE));
                   2079:        afree((void*)cp, ATEMP);
                   2080:        lastp = strrchr(buf, '/');
                   2081:        if (lastp)
                   2082:                *lastp = 0;
                   2083: 
                   2084:        dirnam = (lastp == NULL) ? "." : (lastp == buf) ? "/" : buf;
                   2085:        dirp = opendir(dirnam);
                   2086:        if (dirp == NULL) {
                   2087:                x_putc(BEL);
                   2088:                return;
                   2089:        }
                   2090: 
                   2091:        if (lastp == NULL)
                   2092:                lastp = buf;
                   2093:        else
                   2094:                lastp++;
                   2095:        len = strlen(lastp);
                   2096: 
                   2097:        while ((dp = readdir(dirp)) != NULL)  {
                   2098:                cp = dp->d_name;
                   2099:                if (cp[0] == '.' &&
                   2100:                    (cp[1] == '\0' || (cp[1] == '.' && cp[2] == '\0')))
                   2101:                        continue;       /* always ignore . and .. */
                   2102:                if (strncmp(lastp, cp, len) == 0) {
                   2103:                        if (type        /* for complete */) {
                   2104:                                if (loc == -1)  {
                   2105:                                        (void)strcpy(bug, cp);
                   2106:                                        loc = strlen(cp);
                   2107:                                } else {
                   2108:                                        multi = 1;
                   2109:                                        loc = strmatch(bug, cp);
                   2110:                                        bug[loc] = 0;
                   2111:                                }
                   2112:                        }
                   2113:                        if (type != 1) { /* for list */
                   2114:                                add_stash(dirnam, cp);
                   2115:                        }
                   2116:                }
                   2117:        }
                   2118:        (void)closedir(dirp);
                   2119: 
                   2120:        if (type) {                     /* for complete */
                   2121:                if (loc < 0 ||
                   2122:                    (loc == 0 && type != 2))  {
                   2123:                        x_putc(BEL);
                   2124:                        return;
                   2125:                }
                   2126:                cp = bug + len;
                   2127:                x_ins(cp);
                   2128:                if (!multi)  {
                   2129:                        struct stat statb;
                   2130:                        if (lastp == buf)
                   2131:                                buf[0] = 0;
                   2132:                        else if (lastp == buf + 1)  {
                   2133:                                buf[1] = 0;
                   2134:                                buf[0] = '/';
                   2135:                        }  else
                   2136:                                (void)strcat(buf, "/");
                   2137:                        (void)strcat(buf, bug);
                   2138:                        if (stat(buf, &statb) == 0 && S_ISDIR(statb.st_mode))
                   2139:                                x_ins("/");
                   2140:                        else
                   2141:                                x_ins(" ");
                   2142:                }
                   2143:        }
                   2144:        if (type == 0 ||                /* if list */
                   2145:            (type == 2 && multi)) {     /* or complete-list and ambiguous */
                   2146:                list_stash();
                   2147:        }
                   2148: }
                   2149: 
                   2150: static void
                   2151: compl_command(type)
                   2152: {
                   2153:        register struct tbl *tp;
                   2154:        char    *str;
                   2155:        char    buf [256+1];
                   2156:        char    bug [256+1];
                   2157:        char    *xp;
                   2158:        char    *cp;
                   2159:        int  len;
                   2160:        int  multi;
                   2161:        int  loc;
                   2162: 
                   2163:        /* type == 0 for list, 1 for complete and 2 for complete-list */
                   2164:        str = xcp;
                   2165:        cp = buf;
                   2166:        xp = str;
                   2167:        while (xp != xbuf)  {
                   2168:                --xp;
                   2169:                if (iscfs(*xp))  {
                   2170:                        xp++;
                   2171:                        break;
                   2172:                }
                   2173:        }
                   2174:        if (type)                       /* for complete */
                   2175:                while (*xcp && !iscfs(*xcp))
                   2176:                        x_zotc(*xcp++);
                   2177:        if (type != 1) {                /* for list */
                   2178:                x_maxlen = 0;
                   2179:                XPinit(words, 16);
                   2180:        }
                   2181:        while (*xp && !iscfs(*xp))
                   2182:                *cp++ = *xp++;
                   2183:        *cp = 0;
                   2184: 
                   2185:        len = strlen(buf);
                   2186:        loc = -1;
                   2187:        multi = 0;
                   2188: 
                   2189:        for (twalk(&commands); (tp = tnext()) != NULL; ) {
                   2190:                int     klen;
                   2191: 
                   2192:                if (!(tp->flag&ISSET))
                   2193:                        continue;
                   2194:                klen = strlen(tp->name);
                   2195:                if (klen < len)
                   2196:                        continue;
                   2197:                if (strncmp(buf, tp->name, len) ==0) {
                   2198:                        if (type)  {    /* for complete */
                   2199:                                if (loc == -1)  {
                   2200:                                        (void)strcpy(bug, tp->name);
                   2201:                                        loc = klen;
                   2202:                                } else {
                   2203:                                        multi = 1;
                   2204:                                        loc = strmatch(bug, tp->name);
                   2205:                                        bug[loc] = 0;
                   2206:                                }
                   2207:                        }
                   2208:                        if (type != 1) { /* for list */
                   2209:                                add_stash((char *)0, tp->name);
                   2210:                        }
                   2211:                }
                   2212:        }
                   2213: 
                   2214:        if (type)  {                    /* for complete */
                   2215:                if (loc < 0 ||
                   2216:                    (loc == 0 && type != 2))  {
                   2217:                        x_putc(BEL);
                   2218:                        return;
                   2219:                }
                   2220:                cp = bug + len;
                   2221:                x_ins(cp);
                   2222:                if (!multi)
                   2223:                        x_ins(" ");
                   2224:                else if (type == 2)     /* complete and list rest */
                   2225:                        list_stash();
                   2226:        }
                   2227: 
                   2228:        if (type == 0 ||                /* if list */
                   2229:            (type == 2 && multi)) {     /* or complete-list and ambiguous */
                   2230:                list_stash();
                   2231:        }
                   2232: }
                   2233: 
                   2234: static int
                   2235: strmatch(s1, s2)
                   2236:        register char *s1, *s2;
                   2237: {
                   2238:        register char *p;
                   2239: 
                   2240:        for (p = s1; *p == *s2++ && *p != 0; p++)
                   2241:                ;
                   2242:        return p - s1;
                   2243: }
                   2244: 
                   2245: 
                   2246: 
                   2247: /* NAME:
                   2248:  *      x_set_arg - set an arg value for next function
                   2249:  *
                   2250:  * DESCRIPTION:
                   2251:  *      This is a simple implementation of M-[0-9].
                   2252:  *
                   2253:  * RETURN VALUE:
                   2254:  *      KSTD
                   2255:  */
                   2256: 
                   2257: static int
                   2258: x_set_arg(c)
                   2259:   int c;
                   2260: {
                   2261:   if ((x_arg = (c &= CMASK) - '0') < 0 || x_arg > 9)
                   2262:   {
                   2263:     x_arg = 1;
                   2264:     x_putc(BEL);
                   2265:   }
                   2266:   return KSTD;
                   2267: }
                   2268: 
                   2269: 
                   2270: /* NAME:
                   2271:  *      x_prev_histword - recover word from prev command
                   2272:  *
                   2273:  * DESCRIPTION:
                   2274:  *      This function recovers the last word from the previous 
                   2275:  *      command and inserts it into the current edit line.  If a 
                   2276:  *      numeric arg is supplied then the n'th word from the 
                   2277:  *      start of the previous command is used.  
                   2278:  *      
                   2279:  *      Bound to M-.
                   2280:  *
                   2281:  * RETURN VALUE:
                   2282:  *      KSTD
                   2283:  */
                   2284: 
                   2285: static int
                   2286: x_prev_histword()
                   2287: {
                   2288:   register char *rcp;
                   2289:   char *cp;
                   2290:   char **hp;
                   2291: 
                   2292:   hp = x_histp-1;
                   2293:   if (hp < history || hp > histptr)
                   2294:   {
                   2295:     x_putc(BEL);
                   2296:     return;
                   2297:   }
                   2298:   cp = *hp;
                   2299:   if (x_last_command != x_set_arg)
                   2300:   {
                   2301:     rcp = &cp[strlen(cp) - 1];
                   2302:     /*
                   2303:      * ignore white-space after the last word
                   2304:      */
                   2305:     while (rcp > cp && iscfs(*rcp))
                   2306:       rcp--;
                   2307:     while (rcp > cp && !iscfs(*rcp))
                   2308:       rcp--;
                   2309:     if (iscfs(*rcp))
                   2310:       rcp++;
                   2311:     x_ins(rcp);
                   2312:   }
                   2313:   else
                   2314:   {
                   2315:     int c;
                   2316:     
                   2317:     rcp = cp;
                   2318:     /*
                   2319:      * ignore white-space at start of line
                   2320:      */
                   2321:     while (*rcp && iscfs(*rcp))
                   2322:       rcp++;
                   2323:     while (x_arg-- > 1)
                   2324:     {
                   2325:       while (*rcp && !iscfs(*rcp))
                   2326:        rcp++;
                   2327:       while (*rcp && iscfs(*rcp))
                   2328:        rcp++;
                   2329:     }
                   2330:     cp = rcp;
                   2331:     while (*rcp && !iscfs(*rcp))
                   2332:       rcp++;
                   2333:     c = *rcp;
                   2334:     *rcp = '\0';
                   2335:     x_ins(cp);
                   2336:     *rcp = c;
                   2337:   }
                   2338:   return KSTD;
                   2339: }
                   2340: 
                   2341: /* NAME:
                   2342:  *      x_fold_case - convert word to UPPER/lower case
                   2343:  *
                   2344:  * DESCRIPTION:
                   2345:  *      This function is used to implement M-u,M-l and M-c
                   2346:  *      to upper case, lower case or Capitalize words.
                   2347:  *
                   2348:  * RETURN VALUE:
                   2349:  *      None
                   2350:  */
                   2351: 
                   2352: static int
                   2353: x_fold_case(c)
                   2354:   int c;
                   2355: {
                   2356:   register char        *cp = xcp;
                   2357:   
                   2358:   if (cp == xep)
                   2359:   {
                   2360:     x_putc(BEL);
                   2361:     return 0;
                   2362:   }
                   2363:   c &= 0137;                           /* strip prefixes and case */
                   2364:   if (x_last_command != x_set_arg)
                   2365:     x_arg = 1;
                   2366:   while (x_arg--)
                   2367:   {
                   2368:     /*
                   2369:      * fisrt skip over any white-space
                   2370:      */
                   2371:     while (cp != xep && ismfs(*cp))
                   2372:     {
                   2373:       cp++;
                   2374:     }
                   2375:     /*
                   2376:      * do the first char on its own since it may be
                   2377:      * a different action than for the rest.
                   2378:      */
                   2379:     if (cp != xep)
                   2380:     {
                   2381:       if (c == 'L')                    /* M-l */
                   2382:       {
                   2383:        if (isupper(*cp))
                   2384:          *cp = tolower(*cp);
                   2385:       }
                   2386:       else                             /* M-u or M-c */
                   2387:       {
                   2388:        if (islower(*cp))
                   2389:          *cp = toupper(*cp);
                   2390:       }
                   2391:       cp++;
                   2392:     }
                   2393:     /*
                   2394:      * now for the rest of the word
                   2395:      */
                   2396:     while (cp != xep && !ismfs(*cp))
                   2397:     {
                   2398:       if (c == 'U')                    /* M-u */
                   2399:       {
                   2400:        if (islower(*cp))
                   2401:          *cp = toupper(*cp);
                   2402:       }
                   2403:       else                             /* M-l or M-c */
                   2404:       {
                   2405:        if (isupper(*cp))
                   2406:          *cp = tolower(*cp);
                   2407:       }
                   2408:       cp++;
                   2409:     }
                   2410:   }
                   2411:   x_goto(cp);
                   2412:   return 0;
                   2413: }
                   2414: 
                   2415: /* NAME:
                   2416:  *      x_lastcp - last visible char
                   2417:  *
                   2418:  * SYNOPSIS:
                   2419:  *      x_lastcp()
                   2420:  *
                   2421:  * DESCRIPTION:
                   2422:  *      This function returns a pointer to that  char in the 
                   2423:  *      edit buffer that will be the last displayed on the 
                   2424:  *      screen.  The sequence:
                   2425:  *      
                   2426:  *      for (cp = x_lastcp(); cp > xcp; cp)
                   2427:  *        x_bs(*--cp);
                   2428:  *      
                   2429:  *      Will position the cursor correctly on the screen.
                   2430:  *
                   2431:  * RETURN VALUE:
                   2432:  *      cp or NULL
                   2433:  */
                   2434: 
                   2435: char *
                   2436: x_lastcp()
                   2437: {
                   2438:   register char *rcp;
                   2439:   register int i;
                   2440: 
                   2441:   if (!xlp_valid)
                   2442:   {
                   2443:     for (i = 0, rcp = xbp; rcp < xep && i < x_displen; rcp++)
                   2444:       i += x_size(*rcp);
                   2445:     xlp = rcp;
                   2446:   }
                   2447:   xlp_valid = TRUE;
                   2448:   return (xlp);
                   2449: }
                   2450: 
                   2451: #endif /* EDIT */
                   2452: 
                   2453: ./pdksh/sh/var.c   644    653   1762       27675  5243743667  11030 0ustar  hlu#ifndef lint
                   2454: static char *RCSid = "$Id: var.c,v 1.3 1992/08/10 12:03:25 sjg Exp $";
                   2455: #endif
                   2456: 
                   2457: #include "stdh.h"
                   2458: #include <errno.h>
                   2459: #include <setjmp.h>
                   2460: #include <time.h>
                   2461: #include "sh.h"
                   2462: #include "expand.h"
                   2463: 
                   2464: /*
                   2465:  * Variables
                   2466:  *
                   2467:  * WARNING: unreadable code, needs a rewrite
                   2468:  *
                   2469:  * if (flag&INTEGER), val.i contains integer value, and type contains base.
                   2470:  * otherwise, (val.s + type) contains string value.
                   2471:  * if (flag&EXPORT), val.s contains "name=value" for E-Z exporting.
                   2472:  */
                   2473: char   null [] = "";
                   2474: static struct tbl vtemp;
                   2475: static void     export      ARGS((struct tbl *vp, char *val));
                   2476: static int      special     ARGS((char *name));
                   2477: static void     getspec     ARGS((struct tbl *vp));
                   2478: static void     setspec     ARGS((struct tbl *vp));
                   2479: 
                   2480: /*
                   2481:  * create a new block for function calls and simple commands
                   2482:  * assume caller has allocated and set up e.loc
                   2483:  */
                   2484: void
                   2485: newblock()
                   2486: {
                   2487:        register struct block *l = e.loc;
                   2488:        static char *empty[] = {""};
                   2489: 
                   2490:        ainit(&l->area);
                   2491:        l->argc = 0;
                   2492:        l->argv = empty;
                   2493:        l->exit = l->error = NULL;
                   2494:        tinit(&l->vars, &l->area);
                   2495:        tinit(&l->funs, &l->area);
                   2496: }
                   2497: 
                   2498: /*
                   2499:  * pop a block handling special variables
                   2500:  */
                   2501: void
                   2502: popblock()
                   2503: {
                   2504:        register struct block *l = e.loc;
                   2505:        register struct tbl *vp, **vpp = l->vars.tbls;
                   2506:        register int i;
                   2507: 
                   2508:        e.loc = l->next;        /* pop block */
                   2509:        for (i = l->vars.size; --i >= 0; )
                   2510:                if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL))
                   2511:                        setspec(global(vp->name));
                   2512:        afreeall(&l->area);
                   2513: }
                   2514: 
                   2515: /*
                   2516:  * Search for variable, if not found create globally.
                   2517:  */
                   2518: struct tbl *
                   2519: global(n)
                   2520:        register char *n;
                   2521: {
                   2522:        register struct block *l = e.loc;
                   2523:        register struct tbl *vp;
                   2524:        register int c;
                   2525:        unsigned h = hash(n);
                   2526: 
                   2527:        c = n[0];
                   2528:        if (digit(c)) {
                   2529:                vp = &vtemp;
                   2530:                lastarea = ATEMP;
                   2531:                vp->flag = (DEFINED|RDONLY);
                   2532:                vp->type = 0;
                   2533:                *vp->name = c;  /* should strncpy */
                   2534:                for (c = 0; digit(*n) && c < 1000; n++)
                   2535:                        c = c*10 + *n-'0';
                   2536:                if (c <= l->argc)
                   2537:                        setstr(vp, l->argv[c]);
                   2538:                return vp;
                   2539:        } else
                   2540:        if (!letter(c)) {
                   2541:                vp = &vtemp;
                   2542:                lastarea = ATEMP;
                   2543:                vp->flag = (DEFINED|RDONLY);
                   2544:                vp->type = 0;
                   2545:                *vp->name = c;
                   2546:                if (n[1] != '\0')
                   2547:                        return vp;
                   2548:                vp->flag |= ISSET|INTEGER;
                   2549:                switch (c) {
                   2550:                  case '$':
                   2551:                        vp->val.i = kshpid;
                   2552:                        break;
                   2553:                  case '!':
                   2554:                        vp->val.i = async;
                   2555:                        break;
                   2556:                  case '?':
                   2557:                        vp->val.i = exstat;
                   2558:                        break;
                   2559:                  case '#':
                   2560:                        vp->val.i = l->argc;
                   2561:                        break;
                   2562:                  case '-':
                   2563:                        vp->flag &= ~ INTEGER;
                   2564:                        vp->val.s = getoptions();
                   2565:                        break;
                   2566:                  default:
                   2567:                        vp->flag &= ~(ISSET|INTEGER);
                   2568:                }
                   2569:                return vp;
                   2570:        }
                   2571:        for (l = e.loc; l != NULL; l = l->next) {
                   2572:                vp = tsearch(&l->vars, n, h);
                   2573:                lastarea = &l->area;
                   2574:                if (vp != NULL)
                   2575:                        return vp;
                   2576:                if (l->next == NULL)
                   2577:                        break;
                   2578:        }
                   2579:        vp = tenter(&l->vars, n, h);
                   2580:        vp->flag |= DEFINED;
                   2581:        if (special(n))
                   2582:                vp->flag |= SPECIAL;
                   2583:        return vp;
                   2584: }
                   2585: 
                   2586: /*
                   2587:  * Search for local variable, if not found create locally.
                   2588:  */
                   2589: struct tbl *
                   2590: local(n)
                   2591:        register char *n;
                   2592: {
                   2593:        register struct block *l = e.loc;
                   2594:        register struct tbl *vp;
                   2595:        unsigned h = hash(n);
                   2596: 
                   2597:        if (!letter(*n)) {
                   2598:                vp = &vtemp;
                   2599:                lastarea = ATEMP;
                   2600:                vp->flag = (DEFINED|RDONLY);
                   2601:                vp->type = 0;
                   2602:                return vp;
                   2603:        }
                   2604:        vp = tenter(&l->vars, n, h);
                   2605:        lastarea = &l->area;
                   2606:        vp->flag |= DEFINED;
                   2607:        if (special(n))
                   2608:                vp->flag |= SPECIAL;
                   2609:        return vp;
                   2610: }
                   2611: 
                   2612: /* get variable string value */
                   2613: char *
                   2614: strval(vp)
                   2615:        register struct tbl *vp;
                   2616: {
                   2617:        register char *s;
                   2618:        static char strbuf[40];
                   2619: 
                   2620:        if ((vp->flag&SPECIAL))
                   2621:                getspec(vp);
                   2622:        if (!(vp->flag&ISSET))
                   2623:                return null;    /* special to dollar() */
                   2624:        if (!(vp->flag&INTEGER))        /* string source */
                   2625:                s = vp->val.s + vp->type;
                   2626:        else {                          /* integer source */
                   2627:                register unsigned long n;
                   2628:                register int base;
                   2629: 
                   2630:                s = strbuf + sizeof(strbuf);
                   2631:                n = (vp->val.i < 0) ? -vp->val.i : vp->val.i;
                   2632:                base = (vp->type == 0) ? 10 : vp->type;
                   2633: 
                   2634:                *--s = '\0';
                   2635:                do {
                   2636:                        *--s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[n%base];
                   2637:                        n /= base;
                   2638:                } while (n != 0);
                   2639:                /* todo: should we output base# ? */
                   2640:                if (vp->val.i < 0)
                   2641:                        *--s = '-';
                   2642:        }
                   2643:        return s;
                   2644: }
                   2645: 
                   2646: /* get variable integer value */
                   2647: long
                   2648: intval(vp)
                   2649:        register struct tbl *vp;
                   2650: {
                   2651:        register struct tbl *vq;
                   2652: 
                   2653:        if ((vp->flag&SPECIAL))
                   2654:                getspec(vp);
                   2655:        if ((vp->flag&INTEGER))
                   2656:                return vp->val.i;
                   2657:        vq = &vtemp;
                   2658:        vq->flag = (INTEGER);
                   2659:        vq->type = 0;
                   2660:        if (strint(vq, vp) == NULL)
                   2661:                errorf("%s: bad number\n", vp->val.s);
                   2662:        return vq->val.i;
                   2663: }
                   2664: 
                   2665: /* set variable to string value */
                   2666: void
                   2667: setstr(vq, s)
                   2668:        register struct tbl *vq;
                   2669:        char *s;
                   2670: {
                   2671:        if (!(vq->flag&INTEGER)) { /* string dest */
                   2672:                if ((vq->flag&ALLOC))
                   2673:                        afree((void*)vq->val.s, lastarea);
                   2674:                vq->flag &= ~ (ISSET|ALLOC);
                   2675:                vq->type = 0;
                   2676:                if ((vq->flag&EXPORT))
                   2677:                        export(vq, s);
                   2678:                else
                   2679:                        vq->val.s = strsave(s, lastarea);
                   2680:                vq->flag |= ALLOC;
                   2681:        } else {                /* integer dest */
                   2682:                register struct tbl *vp = &vtemp;       
                   2683:                vp->flag = (DEFINED|ISSET);
                   2684:                vp->type = 0;
                   2685:                vp->val.s = s;
                   2686:                if (strint(vq, vp) == NULL)
                   2687:                        errorf("%s: bad number\n", s);
                   2688:        }
                   2689:        vq->flag |= ISSET;
                   2690:        if ((vq->flag&SPECIAL))
                   2691:                setspec(vq);
                   2692: }
                   2693:        
                   2694: /* convert variable to integer variable */
                   2695: struct tbl *
                   2696: strint(vq, vp)
                   2697:        register struct tbl *vq, *vp;
                   2698: {
                   2699:        register char *s = vp->val.s + vp->type;
                   2700:        register int c;
                   2701:        int base, neg = 0;
                   2702:        
                   2703:        vq->flag |= INTEGER;
                   2704:        if (!(vp->flag&ISSET) || (s == NULL && !(vp->flag&INTEGER))) {
                   2705:                vq->flag &= ~ ISSET;
                   2706:                return NULL;
                   2707:        }
                   2708:        if ((vp->flag&INTEGER)) {
                   2709:                vq->val.i = vp->val.i;
                   2710:                return vq;
                   2711:        }
                   2712:        vq->val.i = 0;
                   2713:        base = 10;
                   2714:        for (c = *s++; c ; c = *s++)
                   2715:                if (c == '-') {
                   2716:                        neg++;
                   2717:                } else if (c == '#') {
                   2718:                        base = vq->type = vq->val.i;
                   2719:                        vq->val.i = 0;
                   2720:                } else if (letnum(c)) {
                   2721:                        if ('0' <= c && c <= '9')
                   2722:                                c -= '0';
                   2723:                        else if ('a' <= c && c <= 'z') /* fuck EBCDIC */
                   2724:                                c -= 'a'-10;
                   2725:                        else if ('A' <= c && c <= 'Z')
                   2726:                                c -= 'A'-10;
                   2727:                        if (c < 0 || c >= base) {
                   2728:                                vq->flag &= ~ ISSET;
                   2729:                                return NULL;
                   2730:                        }
                   2731:                        vq->val.i = (vq->val.i*base) + c;
                   2732:                } else
                   2733:                        break;
                   2734:        if (neg)
                   2735:                vq->val.i = -vq->val.i;
                   2736:        if (vq->type < 2 || vq->type > 36)
                   2737:                vq->type = 0;   /* default base (10) */
                   2738:        return vq;
                   2739: }
                   2740: 
                   2741: /* set variable to integer */
                   2742: void
                   2743: setint(vq, n)
                   2744:        register struct tbl *vq;
                   2745:        long n;
                   2746: {
                   2747:        if (!(vq->flag&INTEGER)) {
                   2748:                register struct tbl *vp = &vtemp;
                   2749:                vp->flag = (ISSET|INTEGER);
                   2750:                vp->type = 0;
                   2751:                vp->val.i = n;
                   2752:                setstr(vq, strval(vp)); /* ? */
                   2753:        } else
                   2754:                vq->val.i = n;
                   2755:        vq->flag |= ISSET;
                   2756:        if ((vq->flag&SPECIAL))
                   2757:                setspec(vq);
                   2758: }
                   2759: 
                   2760: /* set variable from enviroment */
                   2761: import(thing)
                   2762:        char *thing;
                   2763: {
                   2764:        register struct tbl *vp;
                   2765:        register char *val;
                   2766: 
                   2767:        val = strchr(thing, '=');
                   2768:        if (val == NULL)
                   2769:                return 0;
                   2770:        *val = '\0';
                   2771:        vp = local(thing);
                   2772:        *val++ = '=';
                   2773:        vp->flag |= DEFINED|ISSET|EXPORT;
                   2774:        vp->val.s = thing;
                   2775:        vp->type = val - thing;
                   2776:        if ((vp->flag&SPECIAL))
                   2777:                setspec(vp);
                   2778:        return 1;
                   2779: }
                   2780: 
                   2781: /*
                   2782:  * make vp->val.s be "name=value" for quick exporting.
                   2783:  */
                   2784: static void
                   2785: export(vp, val)
                   2786:        register struct tbl *vp;
                   2787:        char *val;
                   2788: {
                   2789:        register char *cp, *xp;
                   2790:        char *op = (vp->flag&ALLOC) ? vp->val.s : NULL;
                   2791: 
                   2792:        xp = (char*)alloc(strlen(vp->name) + strlen(val) + 2, lastarea);
                   2793:        vp->flag |= ALLOC;
                   2794:        vp->val.s = xp;
                   2795:        for (cp = vp->name; (*xp = *cp++) != '\0'; xp++)
                   2796:                ;
                   2797:        *xp++ = '=';
                   2798:        vp->type = xp - vp->val.s; /* offset to value */
                   2799:        for (cp = val; (*xp++ = *cp++) != '\0'; )
                   2800:                ;
                   2801:        if (op != NULL)
                   2802:                afree((void*)op, lastarea);
                   2803: }
                   2804: 
                   2805: /*
                   2806:  * lookup variable (according to (set&LOCAL)),
                   2807:  * set its attributes (INTEGER, RDONLY, EXPORT, TRACE),
                   2808:  * and optionally set its value if an assignment.
                   2809:  */
                   2810: struct tbl *
                   2811: typeset(var, set, clr)
                   2812:        register char *var;
                   2813:        int clr, set;
                   2814: {
                   2815:        register struct tbl *vp;
                   2816:        register char *val;
                   2817: 
                   2818:        /* check for valid variable name, search for value */
                   2819:        val = var;
                   2820:        if (!letter(*val))
                   2821:                return NULL;
                   2822:        for (val++; *val != '\0'; val++)
                   2823:                if (*val == '=')
                   2824:                        break;
                   2825:                else if (letnum(*val))
                   2826:                        ;
                   2827:                else
                   2828:                        return NULL;
                   2829:        if (*val == '=')
                   2830:                *val = '\0';
                   2831:        else
                   2832:                val = NULL;
                   2833:        vp = (set&LOCAL) ? local(var) : global(var);
                   2834:        set &= ~ LOCAL;
                   2835:        if (val != NULL)
                   2836:                *val++ = '=';
                   2837: 
                   2838:        if (!(vp->flag&ISSET))
                   2839:                vp->flag = (vp->flag & ~clr) | set;
                   2840:        else
                   2841:            if (!(vp->flag&INTEGER) && (set&INTEGER)) {
                   2842:                /* string to integer */
                   2843:                vtemp.flag = (ISSET);
                   2844:                vtemp.type = 0;
                   2845:                vtemp.val.s = vp->val.s + vp->type;
                   2846:                if ((vp->flag&ALLOC))
                   2847:                        afree((void*)vp->val.s, lastarea); /* dangerous, used later */
                   2848:                vp->flag &= ~ ALLOC;
                   2849:                vp->flag |= INTEGER;
                   2850:                vp->type = 0;
                   2851:                if (val == NULL && strint(vp, &vtemp) == NULL) {
                   2852:                        vp->flag &= ~ ISSET;
                   2853:                        errorf("%s: bad number\n", vtemp.val.s);
                   2854:                }
                   2855:            } else
                   2856:            if ((clr&INTEGER) && (vp->flag&INTEGER)) {
                   2857:                /* integer to string */
                   2858:                vtemp.val.s = strval(vp);
                   2859:                vp->flag &= ~ INTEGER;
                   2860:                setstr(vp, vtemp.val.s);
                   2861:            }
                   2862: 
                   2863:        vp->flag = (vp->flag & ~clr) | set;
                   2864: 
                   2865:        if (val != NULL) {
                   2866:                if ((vp->flag&RDONLY))
                   2867:                        errorf("cannot set readonly %s\n", var);
                   2868:                if ((vp->flag&INTEGER))
                   2869:                        /* setstr should be able to handle this */
                   2870:                        (void)evaluate(var);
                   2871:                else
                   2872:                        setstr(vp, val);
                   2873:        }
                   2874: 
                   2875:        if ((vp->flag&EXPORT) && !(vp->flag&INTEGER) && vp->type == 0)
                   2876:                export(vp, (vp->flag&ISSET) ? vp->val.s : null);
                   2877: 
                   2878:        return vp;
                   2879: }
                   2880: 
                   2881: void
                   2882: unset(vp)
                   2883:        register struct tbl *vp;
                   2884: {
                   2885:        if ((vp->flag&ALLOC))
                   2886:                afree((void*)vp->val.s, lastarea);
                   2887:        vp->flag &= SPECIAL;    /* Should ``unspecial'' some vars */
                   2888: }
                   2889: 
                   2890: int
                   2891: isassign(s)
                   2892:        register char *s;
                   2893: {
                   2894:        if (!letter(*s))
                   2895:                return (0);
                   2896:        for (s++; *s != '='; s++)
                   2897:                if (*s == 0 || !letnum(*s))
                   2898:                        return (0);
                   2899:        return (1);
                   2900: }
                   2901: 
                   2902: /*
                   2903:  * Make the exported environment from the exported names in the dictionary.
                   2904:  */
                   2905: char **
                   2906: makenv()
                   2907: {
                   2908:        struct block *l = e.loc;
                   2909:        XPtrV env;
                   2910:        register struct tbl *vp, **vpp;
                   2911:        register int i;
                   2912: 
                   2913:        XPinit(env, 64);
                   2914:        for (l = e.loc; l != NULL; l = l->next)
                   2915:                for (vpp = l->vars.tbls, i = l->vars.size; --i >= 0; )
                   2916:                        if ((vp = *vpp++) != NULL
                   2917:                            && (vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) {
                   2918:                                register struct block *l2;
                   2919:                                register struct tbl *vp2;
                   2920:                                unsigned h = hash(vp->name);
                   2921: 
                   2922:                                lastarea = &l->area;
                   2923: 
                   2924:                                /* unexport any redefined instances */
                   2925:                                for (l2 = l->next; l2 != NULL; l2 = l2->next) {
                   2926:                                        vp2 = tsearch(&l2->vars, vp->name, h);
                   2927:                                        if (vp2 != NULL)
                   2928:                                                vp2->flag &= ~ EXPORT;
                   2929:                                }
                   2930:                                if ((vp->flag&INTEGER)) {
                   2931:                                        /* integer to string */
                   2932:                                        char *val;
                   2933:                                        val = strval(vp);
                   2934:                                        vp->flag &= ~ INTEGER;
                   2935:                                        setstr(vp, val);
                   2936:                                }
                   2937:                                XPput(env, vp->val.s);
                   2938:                        }
                   2939:        XPput(env, NULL);
                   2940:        return (char **) XPclose(env);
                   2941: }
                   2942: 
                   2943: /*
                   2944:  * handle special variables with side effects - PATH, SECONDS.
                   2945:  */
                   2946: #define STREQ(a, b) ((*a) == (*b) && strcmp((a), (b)) == 0)
                   2947: static int
                   2948: special(name)
                   2949:        register char * name;
                   2950: {
                   2951:        if (STREQ("PATH", name))
                   2952:                return V_PATH;
                   2953:        if (STREQ("IFS", name))
                   2954:                return V_IFS;
                   2955:        if (STREQ("SECONDS", name))
                   2956:                return V_SECONDS;
                   2957:        if (STREQ("OPTIND", name))
                   2958:                return V_OPTIND;
                   2959:        if (STREQ("MAIL", name))
                   2960:                return V_MAIL;
                   2961:        if (STREQ("MAILPATH", name))
                   2962:                return V_MAILPATH;
                   2963:        if (STREQ("RANDOM", name))
                   2964:                return V_RANDOM;
                   2965: #ifndef EASY_HISTORY
                   2966:        if (STREQ("HISTSIZE", name))
                   2967:                return V_HISTSIZE;
                   2968:        if (STREQ("HISTFILE", name))
                   2969:                return V_HISTFILE;
                   2970: #endif
                   2971:        if (STREQ("FCEDIT", name))
                   2972:                return V_FCEDIT;
                   2973:        if (STREQ("COLUMNS", name))
                   2974:                return V_COLUMNS;
                   2975:        return V_NONE;
                   2976: }
                   2977: 
                   2978: extern time_t time();
                   2979: static time_t  seconds;                /* time SECONDS last set */
                   2980: #ifdef NOSTDHDRS
                   2981: extern int     rand();
                   2982: extern void    srand();
                   2983: #endif
                   2984: 
                   2985: static void
                   2986: getspec(vp)
                   2987:        register struct tbl *vp;
                   2988: {
                   2989:        switch (special(vp->name)) {
                   2990:        case V_SECONDS:
                   2991:                vp->flag &= ~ SPECIAL;
                   2992:                setint(vp, time((time_t *)0) - seconds);
                   2993:                vp->flag |= SPECIAL;
                   2994:                break;
                   2995:        case V_RANDOM:
                   2996:                vp->flag &= ~ SPECIAL;
                   2997:                setint(vp, (rand() & 0x7fff));
                   2998:                vp->flag |= SPECIAL;
                   2999:                break;
                   3000: #ifndef EASY_HISTORY
                   3001:        case V_HISTSIZE:
                   3002:                vp->flag &= ~ SPECIAL;
                   3003:                setint(vp, histsize);
                   3004:                vp->flag |= SPECIAL;
                   3005:                break;
                   3006: #endif
                   3007:        }
                   3008: }
                   3009: 
                   3010: static void
                   3011: setspec(vp)
                   3012:        register struct tbl *vp;
                   3013: {
                   3014:        extern void     mbset(), mpset();
                   3015: 
                   3016:        switch (special(vp->name)) {
                   3017:          case V_PATH:
                   3018:                path = strval(vp);
                   3019:                flushcom(1);    /* clear tracked aliases */
                   3020:                break;
                   3021:          case V_IFS:
                   3022:                setctypes(strval(vp), C_IFS);
                   3023:                break;
                   3024:          case V_SECONDS:
                   3025:                seconds = time((time_t *)0);
                   3026:                break;
                   3027:          case V_OPTIND:
                   3028:                if (intval(vp) == 1)
                   3029:                        resetopts();
                   3030:                break;
                   3031:          case V_MAIL:
                   3032:                mbset(strval(vp));
                   3033:                break;
                   3034:          case V_MAILPATH:
                   3035:                mpset(strval(vp));
                   3036:                break;
                   3037:          case V_RANDOM:
                   3038:                vp->flag &= ~ SPECIAL;
                   3039:                srand((unsigned int)intval(vp));
                   3040:                vp->flag |= SPECIAL;
                   3041:                break;
                   3042: #ifndef EASY_HISTORY
                   3043:          case V_HISTSIZE:
                   3044:                vp->flag &= ~ SPECIAL;
                   3045:                sethistsize(intval(vp));
                   3046:                vp->flag |= SPECIAL;
                   3047:                break;
                   3048:          case V_HISTFILE:
                   3049:                sethistfile(strval(vp));
                   3050:                break;
                   3051: #endif
                   3052:          case V_FCEDIT:
                   3053:                set_editmode(strval(vp));
                   3054:                break;
                   3055:          case V_COLUMNS:
                   3056:                if ((x_cols = intval(vp)) <= 0)
                   3057:                  x_cols=80;
                   3058:                break;
                   3059:        }
                   3060: }
                   3061: 
                   3062: ./pdksh/sh/jobs.c   644    653   1762       47556  5302766161  11163 0ustar  hlu/*
                   3063:  * Process and job control
                   3064:  */
                   3065: #ifndef lint
                   3066: static char *RCSid = "$Id: jobs.c,v 1.5 1992/08/10 12:02:52 sjg Exp $";
                   3067: #endif
                   3068: 
                   3069: /*
                   3070:  * based on version by Ron Natalie, BRL
                   3071:  * modified by Simon J. Gerraty <[email protected]>
                   3072:  *
                   3073:  * TODO:
                   3074:  *     change Proc table to Job table, with array of pids.
                   3075:  *     make %+ be jobs, %- be jobs->next.
                   3076:  *     do not JFREE members of pipeline.
                   3077:  *     consider procs[] related critical sections.
                   3078:  */
                   3079: 
                   3080: #include "stdh.h"
                   3081: #include <errno.h>
                   3082: #include <unistd.h>
                   3083: #include <signal.h>
                   3084: #include <setjmp.h>
                   3085: #include <sys/times.h>
                   3086: #include <sys/wait.h>
                   3087: #include "sh.h"
                   3088: #ifdef JOBS
                   3089: #ifdef _BSDI
                   3090: #define _BSD
                   3091: #define WIFCORED(x) WCOREDUMP(x)
                   3092: #endif
                   3093: #ifdef _BSD
                   3094: #include <sys/ioctl.h>
                   3095: #else
                   3096: #include "termios.h"
                   3097: #endif
                   3098: #endif
                   3099: #ifdef linux
                   3100: #include <fcntl.h>
                   3101: #endif
                   3102: 
                   3103: #ifdef _BSD
                   3104: /*
                   3105:  * These macros are for the benefit of SunOS 4.0.2 and 4.0.3
                   3106:  * SunOS 4.1.1 already defines most of them.
                   3107:  * Clearly these are aimed at SunOS, they may work for other
                   3108:  * BSD systems but I can't promise.
                   3109:  */
                   3110: # ifndef WIFSTOPPED
                   3111: #   define WIFSTOPPED(x)       ((x).w_stopval == WSTOPPED)
                   3112: # endif
                   3113: # ifndef WIFSIGNALED
                   3114: #   define WIFSIGNALED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig != 0)
                   3115: # endif
                   3116: # ifndef WIFEXITED
                   3117: #   define WIFEXITED(x)        ((x).w_stopval != WSTOPPED && (x).w_termsig == 0)
                   3118: # endif
                   3119: # ifndef WSTOPSIG
                   3120: #   define WSTOPSIG(x) ((x).w_stopsig)
                   3121: # endif
                   3122: # ifndef WTERMSIG
                   3123: #   define WTERMSIG(x) ((x).w_termsig)
                   3124: # endif
                   3125: # ifndef WIFCORED
                   3126: #   define WIFCORED(x) ((x).w_coredump)
                   3127: # endif
                   3128: # ifndef WEXITSTATUS
                   3129: #   define WEXITSTATUS(x)      ((x).w_retcode)
                   3130: # endif
                   3131: # ifndef HAVE_WAITPID
                   3132: #   define     waitpid(pid, sp, opts)  wait3(sp, opts, (void*)NULL)
                   3133: # endif
                   3134: #else                                  /* not _BSD */
                   3135: # ifndef WIFCORED
                   3136: #   define     WIFCORED(x)     (!!((x)&0x80)) /* non-standard */
                   3137: # endif
                   3138: #endif
                   3139: 
                   3140: /* as of P1003.1 Draft 12.3:
                   3141:  *     pid_t getpgrp(void);            // Get process group id
                   3142:  *     pid_t setsid(void);             // Create session and Set process group id
                   3143:  *     int setpgid(pid_t pid, pid_t pgid); // Set process group id for job control
                   3144:  */
                   3145: 
                   3146: 
                   3147: #ifdef JOBS
                   3148: #ifdef _BSD                    /* _BSD 4.* */
                   3149: #define        setpgid(p, pg)  setpgrp(p, pg)
                   3150: #define        getpgid(p)      getpgrp(p)
                   3151: #define        tcsetpgrp(fd,p) ioctl(fd, TIOCSPGRP, &(p))
                   3152: #else                          /* POSIX-compatible */
                   3153: #define        getpgid(p)      getpgrp() /* 1003.1 stupidity */
                   3154: #define        killpg(p, s)    kill(-(p), s)
                   3155: #endif
                   3156: #endif
                   3157: 
                   3158: 
                   3159: #ifndef        SIGCHLD
                   3160: #define        SIGCHLD SIGCLD
                   3161: #endif
                   3162: #ifndef WAIT_T
                   3163: #ifdef _BSD
                   3164: #define WAIT_T union wait
                   3165: #else
                   3166: #define WAIT_T int
                   3167: #endif
                   3168: #ifdef _BSDI
                   3169: #undef WAIT_T
                   3170: #define WAIT_T int
                   3171: #endif
                   3172: #endif
                   3173: #ifndef SA_RESTART
                   3174: #define SA_RESTART     0
                   3175: #endif
                   3176: 
                   3177: typedef struct Proc Proc;
                   3178: struct Proc {
                   3179:        Proc   *next;           /* `procs' list link */
                   3180:        int     job;            /* job number: %n */
                   3181:        short   volatile state; /* proc state */
                   3182:        short   volatile notify; /* proc state has changed */
                   3183:        Proc   *prev;           /* prev member of pipeline */
                   3184:        pid_t   proc;           /* process id */
                   3185:        pid_t   pgrp;           /* process group if flag[FMONITOR] */
                   3186:        short   flags;          /* execute flags */
                   3187:        WAIT_T  status;         /* wait status */
                   3188:        clock_t utime, stime;   /* user/system time when JDONE */
                   3189:        char    com [48];       /* command */
                   3190: };
                   3191: 
                   3192: /* proc states */
                   3193: #define        JFREE   0               /* unused proc */
                   3194: #define        JRUN    1               /* foreground */
                   3195: #define JEXIT  2               /* exit termination */
                   3196: #define        JSIGNAL 3               /* signal termination */
                   3197: #define        JSTOP   4               /* stopped */
                   3198: 
                   3199: static Proc *procs = NULL;     /* job/process table */
                   3200: 
                   3201: clock_t        j_utime, j_stime;       /* user and system time for last job a-waited */
                   3202: #ifdef JOBS
                   3203: # ifdef USE_SIGACT
                   3204: sigset_t sm_default, sm_sigchld;       /* signal masks */
                   3205: # else
                   3206: static int     sm_default, sm_sigchld; /* signal masks */
                   3207: # endif
                   3208: static int     our_pgrp;               /* shell's pgrp */
                   3209: #endif
                   3210: static Proc   *j_lastj;                /* last proc created by exchild */
                   3211: static int     j_lastjob = 0;          /* last created job */
                   3212: static int     j_current = 0;          /* current job */
                   3213: static int     j_previous = 0;         /* previous job */
                   3214: 
                   3215: static int      j_waitj     ARGS((Proc *aj, int intr));
                   3216: static void     j_print     ARGS((Proc *j));
                   3217: static int      j_newjob    ARGS((void));
                   3218: static Proc *   j_search    ARGS((int job));
                   3219: static void    j_sigchld   ARGS((int sig));
                   3220:   
                   3221: /* initialize job control */
                   3222: void
                   3223: j_init()
                   3224: {
                   3225: #ifdef JOBS
                   3226: # if defined(NTTYDISC) && defined(TIOCSETD)
                   3227:        int ldisc = NTTYDISC;   /* BSD brain damage */
                   3228: 
                   3229:        if (ttyfd >= 0)
                   3230:                ioctl(ttyfd, TIOCSETD, &ldisc);
                   3231: # endif
                   3232:        our_pgrp = getpgid(0);
                   3233:        sigchld_caught = 0;
                   3234: # ifdef USE_SIGACT
                   3235:        sigemptyset(&sm_default);
                   3236:        sigemptyset(&sm_sigchld);
                   3237:        sigaddset(&sm_sigchld, SIGCHLD);
                   3238: # else
                   3239:        sm_default = 0;
                   3240:        sm_sigchld = sigmask(SIGCHLD);
                   3241:        _TRACE(5, ("j_init: sm_sigchld == 0x%x", sm_sigchld));
                   3242: # endif
                   3243: #endif 
                   3244: #ifndef JOBS
                   3245: # ifdef USE_SIGACT
                   3246:        sigaction(SIGCHLD, &Sigact_dfl, NULL);
                   3247: # else
                   3248: #   ifdef _SYSV
                   3249:        signal(SIGCHLD, SIG_DFL);       /* necessary ??? */
                   3250: #   endif
                   3251: # endif
                   3252: #endif
                   3253: }
                   3254: 
                   3255: /* job cleanup before shell exit */
                   3256: void
                   3257: j_exit()
                   3258: {
                   3259:        register Proc *j;
                   3260:        int killed = 0;
                   3261: 
                   3262: #ifdef JOBS
                   3263:        /* kill stopped jobs */
                   3264:        for (j = procs; j != NULL; j = j->next)
                   3265:                if (j->state == JSTOP) {
                   3266:                        killed ++;
                   3267:                        killpg(j->pgrp, SIGHUP);
                   3268:                        killpg(j->pgrp, SIGCONT);
                   3269:                }
                   3270:        if (killed)
                   3271:                sleep(1);
                   3272: #endif
                   3273:        j_notify();
                   3274: 
                   3275: #ifdef JOBS
                   3276:        if (flag[FMONITOR]) {
                   3277:                flag[FMONITOR] = 0;
                   3278:                j_change();
                   3279:        }
                   3280: #endif
                   3281: }
                   3282: 
                   3283: #ifdef JOBS
                   3284: /* turn job control on or off according to flag[FMONITOR] */
                   3285: void
                   3286: j_change()
                   3287: {
                   3288: #ifdef USE_SIGACT
                   3289:        static struct sigaction old_tstp, old_ttin, old_ttou;
                   3290: #else
                   3291:        static handler_t old_tstp, old_ttin, old_ttou;
                   3292: #endif
                   3293:        if (flag[FMONITOR]) {
                   3294:                if (ttyfd < 0) {
                   3295:                        flag[FMONITOR] = 0;
                   3296:                        shellf("job control requires tty\n");
                   3297:                        return;
                   3298:                }
                   3299: #ifdef USE_SIGACT
                   3300:                Sigact.sa_handler = j_sigchld;
                   3301:                sigemptyset(&Sigact.sa_mask);
                   3302:                Sigact.sa_flags = SA_RESTART;
                   3303:                sigaction(SIGCHLD, &Sigact, NULL);
                   3304:                Sigact.sa_flags = 0;
                   3305:                sigtraps[SIGCHLD].sig_dfl = 1; /* restore on fork */
                   3306:                sigaction(SIGTSTP, &Sigact_ign, &old_tstp);
                   3307:                sigtraps[SIGTSTP].sig_dfl = 1;
                   3308:                sigaction(SIGTTIN, &Sigact_ign, &old_ttin);
                   3309:                sigtraps[SIGTTIN].sig_dfl = 1;
                   3310:                sigaction(SIGTTOU, &Sigact_ign, &old_ttou);
                   3311:                sigtraps[SIGTTOU].sig_dfl = 1;
                   3312: #else
                   3313:                (void) signal(SIGCHLD, j_sigchld);
                   3314:                sigtraps[SIGCHLD].sig_dfl = 1; /* restore on fork */
                   3315:                old_tstp = signal(SIGTSTP, SIG_IGN);
                   3316:                sigtraps[SIGTSTP].sig_dfl = 1;
                   3317:                old_ttin = signal(SIGTTIN, SIG_IGN);
                   3318:                sigtraps[SIGTTIN].sig_dfl = 1;
                   3319:                old_ttou = signal(SIGTTOU, SIG_IGN);
                   3320:                sigtraps[SIGTTOU].sig_dfl = 1;
                   3321: #endif
                   3322: #ifdef USE_SIGACT
                   3323:                sigprocmask(SIG_SETMASK, &sm_default, NULL);
                   3324: #else
                   3325:                sigsetmask(sm_default);
                   3326: #endif
                   3327:                tcsetpgrp(ttyfd, our_pgrp);
                   3328:        } else {
                   3329: #ifdef USE_SIGACT
                   3330:                sigaction(SIGCHLD, &Sigact_dfl, NULL);
                   3331:                sigaction(SIGTSTP, &old_tstp, NULL);
                   3332:                sigtraps[SIGTSTP].sig_dfl = 0;
                   3333:                sigaction(SIGTTIN, &old_ttin, NULL);
                   3334:                sigtraps[SIGTTIN].sig_dfl = 0;
                   3335:                sigaction(SIGTTOU, &old_ttou, NULL);
                   3336:                sigtraps[SIGTTOU].sig_dfl = 0;
                   3337: #else
                   3338:                (void) signal(SIGCHLD, SIG_DFL);
                   3339:                (void) signal(SIGTSTP, old_tstp);
                   3340:                sigtraps[SIGTSTP].sig_dfl = 0;
                   3341:                (void) signal(SIGTTIN, old_ttin);
                   3342:                sigtraps[SIGTTIN].sig_dfl = 0;
                   3343:                (void) signal(SIGTTOU, old_ttou);
                   3344:                sigtraps[SIGTTOU].sig_dfl = 0;
                   3345: #endif
                   3346:        }
                   3347: }
                   3348: #endif
                   3349: 
                   3350: /* execute tree in child subprocess */
                   3351: int
                   3352: exchild(t, flags)
                   3353:        struct op *t;
                   3354:        int flags;
                   3355: {
                   3356:        register int i;
                   3357:        register Proc *j;
                   3358:        int rv = 0;
                   3359:        int forksleep;
                   3360: 
                   3361:        flags &= ~XFORK;
                   3362:        if ((flags&XEXEC))
                   3363:                return execute(t, flags);
                   3364: 
                   3365:        /* get free Proc entry */
                   3366:        for (j = procs; j != NULL; j = j->next)
                   3367:                if (j->state == JFREE)
                   3368:                        goto Found;
                   3369:        j = (Proc*) alloc(sizeof(Proc), APERM);
                   3370:        j->next = procs;
                   3371:        j->state = JFREE;
                   3372:        procs = j;
                   3373:   Found:
                   3374: 
                   3375:        j->prev = ((flags&XPIPEI)) ? j_lastj : NULL;
                   3376:        j->proc = j->pgrp = 0;
                   3377:        j->flags = flags;
                   3378:        j->job = (flags&XPIPEI) ? j_lastjob : j_newjob();
                   3379:        snptreef(j->com, sizeof(j->com), "%T", t); /* save proc's command */
                   3380:        j->com[sizeof(j->com)-1] = '\0';
                   3381:        j->state = JRUN;
                   3382: 
                   3383:        /* stdio buffer must be flushed and invalidated */
                   3384:        for (i = (flags&XXWHL) ? 1 : 0; i < NUFILE; i++)
                   3385:                flushshf(i);
                   3386: 
                   3387:        /* create child process */
                   3388:        forksleep = 0;
                   3389: #ifdef JOBS
                   3390:        /* don't allow SIGCHLD until we are ready */
                   3391: 
                   3392: #ifdef USE_SIGACT
                   3393:        sigprocmask(SIG_SETMASK, &sm_sigchld, NULL);
                   3394: # else
                   3395:        sigsetmask(sm_sigchld);
                   3396: # endif
                   3397: #endif
                   3398:        while ((i = fork()) < 0 && errno == EAGAIN && forksleep < 32) {
                   3399:                if (forksleep) {
                   3400:                        sleep(forksleep);
                   3401:                        forksleep <<= 1;
                   3402:                } else
                   3403:                        forksleep = 1;
                   3404:        }
                   3405:        if (i < 0) {
                   3406:                j->state = JFREE;
                   3407:                errorf("cannot fork - try again\n");
                   3408:        }
                   3409:        j->proc = (i != 0) ? i : getpid();
                   3410: 
                   3411: #ifdef JOBS
                   3412:        /* job control set up */
                   3413:        if (flag[FMONITOR] && !(flags&XXCOM))
                   3414:        {
                   3415:          j->pgrp = !(flags&XPIPEI) ? j->proc : j_lastj->pgrp;
                   3416:          /* do in both parent and child to avoid fork race condition */
                   3417:          if (!(flags&XBGND))
                   3418:            tcsetpgrp(ttyfd, j->pgrp); /* could be trouble */
                   3419:          setpgid(j->proc, j->pgrp);
                   3420:        }
                   3421: #endif
                   3422:        j_lastj = j;
                   3423: 
                   3424:        if (i == 0) {           /* child */
                   3425:                e.oenv = NULL;
                   3426:                if (flag[FTALKING])
                   3427:                        restoresigs();
                   3428:                if ((flags&XBGND) && !flag[FMONITOR])
                   3429:                {
                   3430: #ifdef USE_SIGACT
                   3431:                  sigaction(SIGINT, &Sigact_dfl, NULL);
                   3432:                  sigaction(SIGQUIT, &Sigact_dfl, NULL);
                   3433:                  if (flag[FTALKING])
                   3434:                    sigaction(SIGTERM, &Sigact_dfl, NULL);
                   3435: #else
                   3436:                  signal(SIGINT, SIG_IGN);
                   3437:                  signal(SIGQUIT, SIG_IGN);
                   3438:                  if (flag[FTALKING])
                   3439:                    signal(SIGTERM, SIG_DFL);
                   3440: #endif
                   3441:                        if (!(flags&XPIPEI)) {
                   3442:                                i = open("/dev/null", 0);
                   3443:                                (void) dup2(i, 0);
                   3444:                                close(i);
                   3445:                        }
                   3446:                }
                   3447:                for (j = procs; j != NULL; j = j->next)
                   3448:                        j->state = JFREE;
                   3449:                ttyfd = -1;
                   3450: #ifdef JOBS
                   3451:                /* is this needed in the child? */
                   3452: # ifdef USE_SIGACT
                   3453:                sigprocmask(SIG_SETMASK, &sm_default, NULL);
                   3454: # else
                   3455:                sigsetmask(sm_default);
                   3456: # endif
                   3457: #endif
                   3458:                flag[FMONITOR] = flag[FTALKING] = 0;
                   3459:                cleartraps();
                   3460:                execute(t, flags|XEXEC); /* no return */
                   3461:                /* NOTREACHED */
                   3462:        }
                   3463: 
                   3464:        /* shell (parent) stuff */
                   3465:        if ((flags&XBGND)) { /* async statement */
                   3466:                async = j->proc;
                   3467:                j_previous = j_current;
                   3468:                j_current = j->job;
                   3469:                if (flag[FTALKING])
                   3470:                        j_print(j);
                   3471:        }
                   3472: #ifdef JOBS
                   3473: # ifdef USE_SIGACT
                   3474:        sigprocmask(SIG_SETMASK, &sm_default, NULL);
                   3475: # else
                   3476:        sigsetmask(sm_default);
                   3477: # endif
                   3478: #endif
                   3479:        if (!(flags&XBGND))
                   3480:        {               /* sync statement */
                   3481:                if (!(flags&XPIPE))
                   3482:                        rv = j_waitj(j, 0);
                   3483:        }
                   3484: 
                   3485:        return rv;
                   3486: }
                   3487: 
                   3488: /* wait for last job: pipeline or $() sub-process */
                   3489: int
                   3490: waitlast()
                   3491: {
                   3492:        return j_waitj(j_lastj, 0);
                   3493: }
                   3494: 
                   3495: /* wait for job to complete or change state */
                   3496: static int
                   3497: j_waitj(aj, intr)
                   3498:        Proc *aj;
                   3499:        int intr;               /* interruptable */
                   3500: {
                   3501:        register Proc *j;
                   3502:        int rv = 1;
                   3503:        int ttysig = 0;
                   3504: 
                   3505: #ifdef JOBS
                   3506:        if (flag[FMONITOR])
                   3507:        {
                   3508: # ifdef USE_SIGACT
                   3509:          sigprocmask(SIG_SETMASK, &sm_sigchld, NULL);
                   3510: # else
                   3511:          _TRACE(5, ("j_waitj: sigsetmask(sm_sigchld==0x%x)", sm_sigchld));
                   3512:          sigsetmask(sm_sigchld);
                   3513: # endif
                   3514:        }
                   3515: #endif
                   3516:        /* wait for all members of pipeline */
                   3517:        for (j = aj; j != NULL; j = j->prev) {
                   3518:                /* wait for job to finish, stop, or ^C of built-in wait */
                   3519:                while (j->state == JRUN) {
                   3520: #ifdef JOBS
                   3521:                        if (flag[FMONITOR])
                   3522:                        {
                   3523:                          /*
                   3524:                           * 91-07-07 <sjg@sun0>
                   3525:                           * we don't want to wait for a signal
                   3526:                           * that has already arrived :-)
                   3527:                           */
                   3528:                          if (!sigchld_caught)
                   3529:                          {
                   3530: # ifdef USE_SIGACT
                   3531:                            sigsuspend(&sm_default);
                   3532: # else
                   3533:                            _TRACE(4, ("j_waitj: sigpause(%d), sigchld_caught==%d", sm_default, sigchld_caught));
                   3534:                            sigpause(sm_default);
                   3535:                            _TRACE(4, ("j_waitj: sigpause() returned %d, sigchld_caught==%d", errno, sigchld_caught));
                   3536: # endif /* USE_SIGACT */
                   3537:                          }
                   3538:                        }
                   3539:                        else
                   3540: #endif /* JOBS */
                   3541:                                j_sigchld(0);
                   3542:                        /*
                   3543:                         * Children to reap
                   3544:                         */
                   3545:                        if (sigchld_caught)
                   3546:                          j_reapchld();
                   3547:                        _TRACE(4, ("j_waitj: j->proc==%d, j->com=='%s', j->state==0x%hx, j->status==0x%x, j->notify==%hd", j->proc, j->com, j->state, j->status, j->notify));
                   3548:                        
                   3549:                        if (sigtraps[SIGINT].set && intr)
                   3550:                                goto Break;
                   3551:                }
                   3552:                if (j->state == JEXIT) { /* exit termination */
                   3553:                        if (!(j->flags&XPIPEO))
                   3554:                                rv = WEXITSTATUS(j->status);
                   3555:                        j->notify = 0;
                   3556:                } else
                   3557:                if (j->state == JSIGNAL) { /* signalled to death */
                   3558:                        if (!(j->flags&XPIPEO))
                   3559:                                rv = 0x80 + WTERMSIG(j->status);
                   3560:                        if (WTERMSIG(j->status) == SIGINT ||
                   3561:                            (WTERMSIG(j->status) == SIGPIPE &&
                   3562:                             (j->flags&XPIPEO)))
                   3563:                                j->notify = 0;
                   3564:                        if (WTERMSIG(j->status) == SIGINT ||
                   3565:                            WTERMSIG(j->status) == SIGQUIT)
                   3566:                                ttysig = 1;
                   3567:                } else
                   3568: #ifdef JOBS
                   3569:                if (j->state == JSTOP)
                   3570:                        if (WSTOPSIG(j->status) == SIGTSTP)
                   3571:                                ttysig = 1;
                   3572: #else
                   3573:                ;
                   3574: #endif
                   3575:        }
                   3576: 
                   3577:        /* compute total child time for time statement */
                   3578:        for (j = aj; j != NULL; j = j->prev)
                   3579:                j_utime += j->utime, j_stime += j->stime;
                   3580: 
                   3581:        /* find new current job */
                   3582: #ifdef JOBS
                   3583:        if (aj->state == JSTOP) {
                   3584:                j_previous = j_current;
                   3585:                j_current = aj->job;
                   3586:        } else {
                   3587: #else
                   3588:        if (1) {
                   3589: #endif
                   3590:                int hijob = 0;
                   3591: 
                   3592:                /* todo: this needs to be done in j_notify */
                   3593:                /* todo: figure out what to do with j_previous */
                   3594:                j_current = 0;
                   3595:                for (j = procs; j != NULL; j = j->next)
                   3596:                        if ((j->state == JRUN || j->state == JSTOP)
                   3597:                            && j->job > hijob) {
                   3598:                                hijob = j->job;
                   3599:                                j_current = j->job;
                   3600:                        }
                   3601:        }
                   3602: 
                   3603:   Break:
                   3604: #ifdef JOBS
                   3605:        if (flag[FMONITOR])
                   3606:        {
                   3607:          /* reset shell job control state */
                   3608: # ifdef USE_SIGACT
                   3609:          sigprocmask(SIG_SETMASK, &sm_default, NULL);
                   3610: # else
                   3611:          sigsetmask(sm_default);
                   3612: # endif
                   3613:          tcsetpgrp(ttyfd, our_pgrp);
                   3614:        }
                   3615: #endif
                   3616:        if (ttysig)
                   3617:                fputc('\n', shlout);
                   3618:        j_notify();
                   3619: 
                   3620:        return rv;
                   3621: }
                   3622: 
                   3623: /* SIGCHLD handler to reap children */
                   3624: /*
                   3625:  * 91-07-07 <sjg@sun0>
                   3626:  * On the Sun SS2 this appears to get called
                   3627:  * too quickly!
                   3628:  * So just record the event and process later.
                   3629:  */
                   3630: static void
                   3631: j_sigchld(sig)
                   3632:        int sig;
                   3633: {
                   3634:        sigchld_caught++;       /* acknowledge it */
                   3635: }
                   3636: 
                   3637: /*
                   3638:  * 91-07-07 <sjg@sun0>
                   3639:  * This now gets called when j_sigchld()
                   3640:  * has recorded some signals...
                   3641:  */
                   3642: j_reapchld()
                   3643: {
                   3644:        struct tms t0, t1;
                   3645: #if defined(JOBS)
                   3646: # ifdef USE_SIGACT
                   3647:        sigset_t        sm_old;
                   3648: 
                   3649:        sigprocmask(SIG_SETMASK, NULL, &sm_old);
                   3650: # else
                   3651:        int sm_old;
                   3652: 
                   3653:        sm_old = sigblock(0);   /* just get current mask */
                   3654:        _TRACE(5, ("j_reapchld: sm_old==0x%x, sigchld_caught==%d", sm_old, sigchld_caught));
                   3655: # endif
                   3656: #endif
                   3657:        (void) times(&t0);
                   3658: 
                   3659:        do {
                   3660:                register Proc *j;
                   3661:                int pid;
                   3662:                WAIT_T status;
                   3663: #ifdef JOBS
                   3664:                if (flag[FMONITOR])
                   3665:                        pid = waitpid(-1, &status, (WNOHANG|WUNTRACED));
                   3666:                else
                   3667: #endif
                   3668:                        pid = wait(&status);
                   3669:                if (pid < 0 && errno == ECHILD)
                   3670:                {
                   3671:                  /* no children - what are we doing here? */
                   3672:                  _TRACE(5, ("j_reapchld: no children"));
                   3673:                  sigchld_caught = 0;
                   3674:                  break;
                   3675:                }
                   3676:                if (pid <= 0)   /* return if would block (0) ... */
                   3677:                        break;  /* ... or no children or interrupted (-1) */
                   3678:                (void) times(&t1);
                   3679: 
                   3680:                _TRACE(5, ("j_reapchld: looking for pid==%d", pid));
                   3681: 
                   3682:                for (j = procs; j != NULL; j = j->next)
                   3683:                {
                   3684:                  _TRACE(6, ("j_reapchld: j->proc==%d, j->com=='%s', j->state==0x%hx, j->status==0x%x, j->notify==%hd", j->proc, j->com, j->state, j->status, j->notify));
                   3685:                  if (j->state != JFREE && j->proc == pid)
                   3686:                    goto Found;
                   3687:                }
                   3688:                _TRACE(5, ("j_reapchld: did not find pid==%d", pid));
                   3689:                continue;
                   3690:          Found:
                   3691:                _TRACE(5, ("j_reapchld: found pid==%d", pid));
                   3692:                j->notify = 1;
                   3693:                j->status = status;
                   3694: #ifdef JOBS
                   3695:                if (WIFSTOPPED(status))
                   3696:                        j->state = JSTOP;
                   3697:                else
                   3698: #endif
                   3699:                if (WIFEXITED(status))
                   3700:                        j->state = JEXIT;
                   3701:                else
                   3702:                if (WIFSIGNALED(status))
                   3703:                        j->state = JSIGNAL;
                   3704: 
                   3705:                /* compute child's time */
                   3706:                /* todo: what does a stopped job do? */
                   3707:                j->utime = t1.tms_cutime - t0.tms_cutime;
                   3708:                j->stime = t1.tms_cstime - t0.tms_cstime;
                   3709:                t0 = t1;
                   3710: #ifdef JOBS
                   3711: # ifdef USE_SIGACT
                   3712:                sigprocmask(SIG_BLOCK, &sm_sigchld, NULL);
                   3713: # else
                   3714:                sigblock(sm_sigchld);
                   3715: # endif
                   3716: #endif
                   3717:                if (--sigchld_caught < 0) /* reduce the count */
                   3718:                  sigchld_caught = 0;
                   3719: #ifdef JOBS
                   3720: # ifdef USE_SIGACT
                   3721:                sigprocmask(SIG_SETMASK, &sm_old, NULL);
                   3722: # else
                   3723:                _TRACE(5, ("j_reapchld: j->proc==%d, j->com=='%s', j->state==0x%hx, j->status==0x%x, j->notify==%hd", j->proc, j->com, j->state, j->status, j->notify));
                   3724:                sigsetmask(sm_old); /* restore old mask */
                   3725: # endif
                   3726: #endif
                   3727:                
                   3728: #ifdef JOBS
                   3729:        } while (flag[FMONITOR]);
                   3730: #else
                   3731:        } while (0);            /* only once if wait()ing */
                   3732: #endif
                   3733: /*
                   3734:  * this should be safe
                   3735:  */
                   3736: #if defined(_SYSV) && !defined(JOBS) && !defined(USE_SIGACT)
                   3737:        signal(SIGCHLD, j_sigchld);
                   3738: #if 0
                   3739:        /* why was this here??? */
                   3740:        signal(SIGCLD, SIG_DFL);
                   3741: #endif
                   3742: #endif
                   3743: }
                   3744: 
                   3745: j_reap()
                   3746: {
                   3747:   if (sigchld_caught)
                   3748:     j_reapchld();
                   3749: /*
                   3750:  * now done in j_reapchld()
                   3751:  */
                   3752: #if 0 && defined(_SYSV) && !defined(JOBS) && !defined(USE_SIGACT)
                   3753:        signal(SIGCHLD, j_sigchld);
                   3754:        signal(SIGCLD, SIG_DFL);
                   3755: #endif
                   3756:        return(0);
                   3757: }
                   3758: 
                   3759: /* wait for child, interruptable */
                   3760: int
                   3761: waitfor(job)
                   3762:        int job;
                   3763: {
                   3764:        register Proc *j;
                   3765: 
                   3766:        if (job == 0 && j_current == 0)
                   3767:                errorf("no current job\n");
                   3768:        j = j_search((job == 0) ? j_current : job);
                   3769:        if (j == NULL)
                   3770:                errorf("no such job: %d\n", job);
                   3771:        if (flag[FTALKING])
                   3772:                j_print(j);
                   3773:        if (e.interactive) {    /* flush stdout, shlout */
                   3774:                fflush(shf[1]);
                   3775:                fflush(shf[2]);
                   3776:        }
                   3777:        return j_waitj(j, 1);
                   3778: }
                   3779: 
                   3780: /* kill (built-in) a job */
                   3781: void
                   3782: j_kill(job, sig)
                   3783:        int job;
                   3784:        int sig;
                   3785: {
                   3786:        register Proc *j;
                   3787: 
                   3788:        j = j_search(job);
                   3789:        if (j == NULL)
                   3790:                errorf("cannot find job\n");
                   3791:        if (j->pgrp == 0) {     /* !flag[FMONITOR] */
                   3792:                if (kill(j->proc, sig) < 0) /* todo: all member of pipeline */
                   3793:                        errorf("kill: %s\n", strerror(errno));
                   3794: #ifdef JOBS
                   3795:        } else {
                   3796:                if (sig == SIGTERM || sig == SIGHUP)
                   3797:                        (void) killpg(j->pgrp, SIGCONT);
                   3798:                if (killpg(j->pgrp, sig) < 0)
                   3799:                        errorf("killpg: %s\n", strerror(errno));
                   3800: #endif
                   3801:        }
                   3802: }
                   3803: 
                   3804: #ifdef JOBS
                   3805: 
                   3806: /* fg and bg built-ins */
                   3807: int
                   3808: j_resume(job, bg)
                   3809:        int job;
                   3810:        int bg;
                   3811: {
                   3812:        register Proc *j; 
                   3813:        
                   3814:        j = j_search((job == 0) ? j_current : job);
                   3815:        if (j == NULL)
                   3816:                errorf("cannot find job\n", job);
                   3817:        if (j->pgrp == 0)
                   3818:                errorf("job not job-controlled\n");
                   3819: 
                   3820:        j->state = JRUN;
                   3821:        j_print(j);
                   3822:        flushshf(2);
                   3823: 
                   3824:        if (!bg)
                   3825:                tcsetpgrp(ttyfd, j->pgrp); /* attach shell to job */
                   3826:        if (killpg(j->pgrp, SIGCONT) < 0)
                   3827:                errorf("cannot continue job %%%d\n", job);
                   3828:        if (!bg)
                   3829:                return j_waitj(j, 0);
                   3830:        return 0;
                   3831: }
                   3832: 
                   3833: #endif
                   3834: 
                   3835: /* list jobs for jobs built-in */
                   3836: void
                   3837: j_jobs()
                   3838: {
                   3839:        register Proc *j; 
                   3840: 
                   3841:        for (j = procs; j != NULL; j = j->next)
                   3842:                if (j->state != JFREE)
                   3843:                        j_print(j);
                   3844: }
                   3845: 
                   3846: /* list jobs for top-level notification */
                   3847: void
                   3848: j_notify()
                   3849: {
                   3850:        register Proc *j; 
                   3851: 
                   3852:        /*
                   3853:         * since reaping is no longer done in the signal handler
                   3854:         * we had better try here...
                   3855:         */
                   3856:        if (sigchld_caught)
                   3857:          j_reapchld();
                   3858:        
                   3859:        for (j = procs; j != NULL; j = j->next) {
                   3860:                if (j->state == JEXIT && !flag[FTALKING])
                   3861:                        j->notify = 0;
                   3862:                if (j->state != JFREE && j->notify)
                   3863:                        j_print(j);
                   3864:                if (j->state == JEXIT || j->state == JSIGNAL)
                   3865:                        j->state = JFREE;
                   3866:                j->notify = 0;
                   3867:        }
                   3868: }
                   3869: 
                   3870: static void
                   3871: j_print(j)
                   3872:        register Proc *j;
                   3873: {
                   3874:        char buf [64], *s = buf;
                   3875: 
                   3876:        switch (j->state) {
                   3877:          case JRUN:
                   3878:                s = "Running";
                   3879:                break;
                   3880: 
                   3881: #ifdef JOBS
                   3882:          case JSTOP:
                   3883:                strcpy(buf, "Stopped ");
                   3884:                s = strchr(sigtraps[WSTOPSIG(j->status)].mess, '(');
                   3885:                if (s != NULL)
                   3886:                        strcat(buf, s);
                   3887:                s = buf;
                   3888:                break;
                   3889: #endif
                   3890: 
                   3891:          case JEXIT: {
                   3892:                int rv;
                   3893:                rv = WEXITSTATUS(j->status);
                   3894:                sprintf(buf, "Done (%d)", rv);
                   3895:                if (rv == 0)
                   3896:                        *strchr(buf, '(') = 0;
                   3897:                j->state = JFREE;
                   3898:                } break;
                   3899: 
                   3900:          case JSIGNAL: {
                   3901:                int sig = WTERMSIG(j->status);
                   3902:                char *n = sigtraps[sig].mess;
                   3903:                if (n != NULL)
                   3904:                        sprintf(buf, "%s", n);
                   3905:                else
                   3906:                        sprintf(buf, "Signal %d", sig);
                   3907:                if (WIFCORED(j->status))
                   3908:                        strcat(buf, " - core dumped");
                   3909:                j->state = JFREE;
                   3910:                } break;
                   3911: 
                   3912:          default:
                   3913:                s = "Hideous job state";
                   3914:                j->state = JFREE;
                   3915:                break;
                   3916:        }
                   3917:        shellf("%%%-2d%c %5d %-20s %s%s\n", j->job,
                   3918:               (j_current==j->job) ? '+' : (j_previous==j->job) ? '-' : ' ',
                   3919:               j->proc, s, j->com, (j->flags&XPIPEO) ? "|" : "");
                   3920: }
                   3921: 
                   3922: /* convert % sequence to job number */
                   3923: int
                   3924: j_lookup(cp)
                   3925:        char *cp;
                   3926: {
                   3927:        register Proc *j;
                   3928:        int len, job = 0;
                   3929: 
                   3930:        if (*cp == '%')         /* leading % is optional */
                   3931:                cp++;
                   3932:        switch (*cp) {
                   3933:          case '\0':
                   3934:          case '+':
                   3935:                job = j_current;
                   3936:                break;
                   3937: 
                   3938:          case '-':
                   3939:                job = j_previous;
                   3940:                break;
                   3941: 
                   3942:          case '0': case '1': case '2': case '3': case '4':
                   3943:          case '5': case '6': case '7': case '8': case '9': 
                   3944:                job = atoi(cp);
                   3945:                break;
                   3946: 
                   3947:          case '?':             /* %?string */
                   3948:                for (j = procs; j != NULL; j = j->next)
                   3949:                        if (j->state != JFREE && strstr(j->com, cp+1) != NULL)
                   3950:                                job = j->job;
                   3951:                break;
                   3952: 
                   3953:          default:              /* %string */
                   3954:                len = strlen(cp);
                   3955:                for (j = procs; j != NULL; j = j->next)
                   3956:                        if (j->state != JFREE && strncmp(cp, j->com, len) == 0)
                   3957:                                job = j->job;
                   3958:                break;
                   3959:        }
                   3960:        if (job == 0)
                   3961:                errorf("%s: no such job\n", cp);
                   3962:        return job;
                   3963: }
                   3964: 
                   3965: /* are any stopped jobs ? */
                   3966: #ifdef JOBS
                   3967: int
                   3968: j_stopped()
                   3969: {
                   3970:        register Proc *j; 
                   3971: 
                   3972:        for (j = procs; j != NULL; j = j->next)
                   3973:                if (j->state == JSTOP)
                   3974:                        return 1;
                   3975:        return 0;
                   3976: }
                   3977: #endif
                   3978: 
                   3979: /* create new job number */
                   3980: static int
                   3981: j_newjob()
                   3982: {
                   3983:        register Proc *j; 
                   3984:        register int max = 0;
                   3985:        
                   3986:        j_lastjob ++;
                   3987:        for (j = procs; j != NULL; j = j->next)
                   3988:                if (j->state != JFREE && j->job)
                   3989:                        if (j->job > max)
                   3990:                                max = j->job;
                   3991:        if (j_lastjob > max)
                   3992:                j_lastjob = max + 1;
                   3993:        return j_lastjob;
                   3994: }
                   3995: 
                   3996: /* search for job by job number */
                   3997: static Proc *
                   3998: j_search(job)
                   3999:        int job;
                   4000: {
                   4001:        register Proc *j;
                   4002: 
                   4003:        for (j = procs; j != NULL; j = j->next)
                   4004:                if (j->state != JFREE && job == j->job && !(j->flags&XPIPEO))
                   4005:                        return j;
                   4006:        return NULL;
                   4007: }
                   4008: 
                   4009: ./pdksh/sh/trace.c   644    653   1762        6007  5243743615  11271 0ustar  hlu/* NAME:
                   4010:  *      trace.c - a simple trace facility
                   4011:  *
                   4012:  * SYNOPSIS:
                   4013:  *      TRACE(level, (fmt [, ...]));
                   4014:  *
                   4015:  * DESCRIPTION:
                   4016:  *      This module provides a simple trace facility via
                   4017:  *      a call to checkpoint() which opens a log file and writes 
                   4018:  *      an entry and closes the log (so that process crashes 
                   4019:  *      won't destroy the log :-).  checkpoint() takes options 
                   4020:  *      like printf().  If Trace_log is not initialized then
                   4021:  *      stderr is used.
                   4022:  *      
                   4023:  *      The header file trace.h defines a macro TRACE() which 
                   4024:  *      is useful in that it allows checkpoint to be called 
                   4025:  *      based on the value of Trace_level, and the calls can be 
                   4026:  *      eliminated by undefining USE_TRACE.
                   4027:  *
                   4028:  * RETURN VALUE:
                   4029:  *      None.
                   4030:  *
                   4031:  * FILES:
                   4032:  *      None.
                   4033:  *
                   4034:  * SEE ALSO:
                   4035:  *      
                   4036:  *
                   4037:  * BUGS:
                   4038:  *      
                   4039:  *
                   4040:  * AMENDED:
                   4041:  *      91/11/22  22:53:56  (sjg)
                   4042:  *
                   4043:  * RELEASED:
                   4044:  *      91/11/22  22:54:17  v1.2
                   4045:  *
                   4046:  *      @(#)Copyright (c) 1990 Simon J. Gerraty.
                   4047:  */
                   4048: #ifdef USE_TRACE
                   4049: 
                   4050: #ifndef lint
                   4051: static char  sccs_id[] = "@(#)trace.c     1.2  91/11/22  22:53:56  (sjg)";
                   4052: #endif
                   4053: 
                   4054: /* include files */
                   4055: #include <stdio.h>
                   4056: #ifdef __STDC__
                   4057: # include <stdlib.h>
                   4058: #endif
                   4059: 
                   4060: #define EXTERN
                   4061: #include "trace.h"
                   4062: #undef EXTERN
                   4063: 
                   4064: /* some useful #defines */
                   4065: #ifndef ENTRY
                   4066: # define ENTRY
                   4067: # define LOCAL static
                   4068: # define BOOLEAN int
                   4069: #endif
                   4070: #ifndef TRUE
                   4071: # define TRUE  1
                   4072: # define FALSE 0
                   4073: #endif
                   4074: #ifndef ARGS
                   4075: # if defined(__STDC__) || defined(PROTO)
                   4076: #   define ARGS(p) p
                   4077: # else
                   4078: #   define ARGS(p) ()
                   4079: # endif
                   4080: #endif
                   4081: 
                   4082: 
                   4083: /* NAME:
                   4084:  *      checkpoint - write a logfile entry
                   4085:  *
                   4086:  * SYNOPSIS:
                   4087:  *      checkpoint(fmt, ...)
                   4088:  *
                   4089:  * DESCRIPTION:
                   4090:  *      This function takes a variable number or args  
                   4091:  *      like the printf(3S) family of functions.
                   4092:  *
                   4093:  * RETURN VALUE:
                   4094:  *      None
                   4095:  */
                   4096: extern char * _CDECL strdup    ARGS((char *s));
                   4097:   
                   4098: #ifdef __STDC__
                   4099: # include <stdarg.h>
                   4100: 
                   4101: ENTRY void _CDECL
                   4102: checkpoint(fmt)
                   4103:        char *fmt;
                   4104: {
                   4105:   int c;
                   4106:   va_list arg_ptr;
                   4107:   FILE *fp;
                   4108:   register char *rcp;
                   4109:   char  *mode;
                   4110:   static  setup;
                   4111:   
                   4112:   va_start(arg_ptr, fmt);
                   4113: #else  /* __STDC__ */
                   4114: # include <varargs.h>
                   4115:   
                   4116: ENTRY void _CDECL
                   4117: checkpoint(va_alist)
                   4118:   va_dcl
                   4119: {
                   4120:   extern char *getenv  ARGS((char *var));
                   4121:   char *fmt;
                   4122:   int c;
                   4123:   va_list arg_ptr;
                   4124:   FILE *fp;
                   4125:   register char *rcp;
                   4126:   char  *mode;
                   4127:   static  setup;
                   4128:   
                   4129:   va_start(arg_ptr);
                   4130:   fmt = va_arg(arg_ptr, char *);
                   4131: #endif /* __STDC__ */
                   4132:   
                   4133:   /* 42 is a "magic" number */
                   4134:   if (setup == 42)
                   4135:     mode = "a";
                   4136:   else
                   4137:   {
                   4138:     if (Trace_level == 0 && (rcp = getenv("TRACE_LEVEL")))
                   4139:       Trace_level = atoi(rcp);
                   4140:     if (Trace_log == NULL || *Trace_log == '\0')
                   4141:     {
                   4142:       if (rcp = getenv("TRACE_LOG"))
                   4143:        Trace_log = strdup(rcp);
                   4144:       else
                   4145:        Trace_log = NULL;
                   4146:     }
                   4147:     setup = 42;
                   4148:     mode= "w";
                   4149:   }
                   4150:   if (Trace_log)
                   4151:     fp = fopen(Trace_log, mode);
                   4152:   else
                   4153:     fp = stderr;
                   4154:   if (fp != (FILE *)NULL)
                   4155:   {
                   4156:     vfprintf(fp, fmt, arg_ptr);
                   4157:     fputc('\n', fp);
                   4158:     if (fp == stderr)
                   4159:       fflush(fp);
                   4160:     else
                   4161:       fclose(fp);
                   4162:   }
                   4163: }
                   4164: 
                   4165: #endif /* USE_TRACE */
                   4166: 
                   4167: /* This lot (for GNU-Emacs) goes at the end of the file. */
                   4168: /* 
                   4169:  * Local Variables:
                   4170:  * version-control:t
                   4171:  * comment-column:40
                   4172:  * End:
                   4173:  */
                   4174: ./pdksh/sh/exec.c   644    653   1762       44176  5243743655  11154 0ustar  hlu/*
                   4175:  * execute command tree
                   4176:  */
                   4177: 
                   4178: #ifndef lint
                   4179: static char *RCSid = "$Id: exec.c,v 1.4 1992/08/10 12:02:38 sjg Exp $";
                   4180: #endif
                   4181: 
                   4182: #include "stdh.h"
                   4183: #include <errno.h>
                   4184: #include <signal.h>
                   4185: #include <setjmp.h>
                   4186: #include <unistd.h>
                   4187: #include <fcntl.h>
                   4188: #include <sys/stat.h>
                   4189: #include "sh.h"
                   4190: #include "edit.h"
                   4191: 
                   4192: static int      comexec     ARGS((struct op *t, char **vp, char **ap, int flags));
                   4193: #ifdef SHARPBANG
                   4194: static void     scriptexec  ARGS((struct op *tp, char **ap));
                   4195: #endif
                   4196: static void     iosetup     ARGS((struct ioword *iop));
                   4197: static int      herein      ARGS((char *hname, int sub));
                   4198: static void     echo        ARGS((char **vp, char **ap));
                   4199: static char    *do_selectargs ARGS((char **ap, char *));
                   4200: static int     selread     ARGS((void));
                   4201: 
                   4202: 
                   4203: /*
                   4204:  * handle systems that don't have F_SETFD
                   4205:  */
                   4206: #ifndef F_SETFD
                   4207: # ifndef MAXFD
                   4208: #   define  MAXFD 64
                   4209: # endif
                   4210: /*
                   4211:  * a bit field would be smaller, but this
                   4212:  * will work
                   4213:  */
                   4214: static char clexec_tab[MAXFD+1];
                   4215: 
                   4216: /* this is so that main() can clear it */
                   4217: void
                   4218: init_clexec()
                   4219: {
                   4220:   (void) memset(clexec_tab, 0, sizeof(clexec_tab)-1);
                   4221: }
                   4222: 
                   4223: int
                   4224: fd_clexec(fd)
                   4225:   int fd;
                   4226: {
                   4227:   if (fd < sizeof(clexec_tab))
                   4228:   {
                   4229:     clexec_tab[fd] = 1;
                   4230:     return 0;
                   4231:   }
                   4232:   return -1;
                   4233: }
                   4234: #endif
                   4235: 
                   4236: 
                   4237: /*
                   4238:  * execute command tree
                   4239:  */
                   4240: int
                   4241: execute(t, flags)
                   4242:        register struct op *t;
                   4243:        volatile int flags;     /* if XEXEC don't fork */
                   4244: {
                   4245:        int i;
                   4246:        int volatile rv = 0;
                   4247:        int pv[2];
                   4248:        register char **ap;
                   4249:        char *s, *cp;
                   4250:        struct ioword **iowp;
                   4251: 
                   4252:        if (t == NULL)
                   4253:                return 0;
                   4254: 
                   4255:        if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE)
                   4256:                return exchild(t, flags); /* run in sub-process */
                   4257: 
                   4258:        newenv(E_EXEC);
                   4259:        if (trap)
                   4260:                runtraps();
                   4261:  
                   4262:        if (t->ioact != NULL || t->type == TPIPE) {
                   4263:                e.savefd = (short*) alloc(sizeofN(short, NUFILE), ATEMP);
                   4264:                for (i = 0; i < NUFILE; i++)
                   4265:                        e.savefd[i] = 0; /* not redirected */
                   4266:                /* mark fd 0/1 in-use if pipeline */
                   4267:                if (flags&XPIPEI)
                   4268:                        e.savefd[0] = -1;
                   4269:                if (flags&XPIPEO)
                   4270:                        e.savefd[1] = -1;
                   4271:        }
                   4272: 
                   4273:        /* do redirection, to be restored in quitenv() */
                   4274:        if (t->ioact != NULL)
                   4275:                for (iowp = t->ioact; *iowp != NULL; iowp++)
                   4276:                        iosetup(*iowp);
                   4277: 
                   4278:        switch(t->type) {
                   4279:          case TCOM:
                   4280:                e.type = E_TCOM;
                   4281:                rv = comexec(t, eval(t->vars, DOTILDE),
                   4282:                             eval(t->args, DOBLANK|DOGLOB|DOTILDE), flags);
                   4283:                break;
                   4284: 
                   4285:          case TPAREN:
                   4286:                exstat = rv = execute(t->left, flags|XFORK);
                   4287:                break;
                   4288: 
                   4289:          case TPIPE:
                   4290:                flags |= XFORK;
                   4291:                flags &= ~XEXEC;
                   4292:                e.savefd[0] = savefd(0);
                   4293:                e.savefd[1] = savefd(1);
                   4294:                flags |= XPIPEO;
                   4295:                (void) dup2(e.savefd[0], 0); /* stdin of first */
                   4296:                while (t->type == TPIPE) {
                   4297:                        openpipe(pv);
                   4298:                        (void) dup2(pv[1], 1);  /* stdout of curr */
                   4299:                        exchild(t->left, flags);
                   4300:                        (void) dup2(pv[0], 0);  /* stdin of next */
                   4301:                        closepipe(pv);
                   4302:                        flags |= XPIPEI;
                   4303:                        t = t->right;
                   4304:                }
                   4305:                flags &= ~ XPIPEO;
                   4306:                (void) dup2(e.savefd[1], 1); /* stdout of last */
                   4307:                exchild(t, flags);
                   4308:                (void) dup2(e.savefd[0], 0); /* close pipe in */
                   4309:                if (!(flags&XBGND))
                   4310:                        exstat = rv = waitlast();
                   4311:                break;
                   4312: 
                   4313:          case TLIST:
                   4314:                while (t->type == TLIST) {
                   4315:                        execute(t->left, 0);
                   4316:                        t = t->right;
                   4317:                }
                   4318:                rv = execute(t, 0);
                   4319:                break;
                   4320: 
                   4321:          case TASYNC:
                   4322:                rv = execute(t->left, flags|XBGND|XFORK);
                   4323:                break;
                   4324: 
                   4325:          case TOR:
                   4326:          case TAND:
                   4327:                rv = execute(t->left, 0);
                   4328:                if (t->right != NULL && (rv == 0) == (t->type == TAND))
                   4329:                        rv = execute(t->right, 0);
                   4330:                break;
                   4331: 
                   4332:          case TFOR:
                   4333:                e.type = E_LOOP;
                   4334:                ap = (t->vars != NULL) ?
                   4335:                        eval(t->vars, DOBLANK|DOGLOB|DOTILDE) : e.loc->argv + 1;
                   4336:                while ((i = setjmp(e.jbuf)))
                   4337:                        if (i == LBREAK)
                   4338:                                goto Break1;
                   4339:                while (*ap != NULL) {
                   4340:                        setstr(global(t->str), *ap++);
                   4341:                        rv = execute(t->left, 0);
                   4342:                }
                   4343:          Break1:
                   4344:                break;
                   4345: 
                   4346:          case TSELECT:
                   4347:                e.type = E_LOOP;
                   4348:                ap = (t->vars != NULL) ?
                   4349:                        eval(t->vars, DOBLANK|DOGLOB|DOTILDE) : e.loc->argv + 1;
                   4350:                while ((i = setjmp(e.jbuf)))
                   4351:                        if (i == LBREAK)
                   4352:                                goto Break1;
                   4353:                signal(SIGINT, trapsig); /* needs change to trapsig */
                   4354:                cp = NULL;
                   4355:                for (;;) {
                   4356:                        if ((cp = do_selectargs(ap, cp)) == (char *)1)
                   4357:                                break;
                   4358:                        setstr(global(t->str), cp);
                   4359:                        rv = execute(t->left, 0);
                   4360:                }
                   4361:                break;
                   4362:                
                   4363:          case TWHILE:
                   4364:          case TUNTIL:
                   4365:                e.type = E_LOOP;
                   4366:                while ((i = setjmp(e.jbuf)))
                   4367:                        if (i == LBREAK)
                   4368:                                goto Break2;
                   4369:                while ((execute(t->left, 0) == 0) == (t->type == TWHILE))
                   4370:                        rv = execute(t->right, XXWHL);
                   4371:          Break2:
                   4372:                break;
                   4373: 
                   4374:          case TIF:
                   4375:          case TELIF:
                   4376:                if (t->right == NULL)
                   4377:                        break;  /* should be error */
                   4378:                rv = execute(t->left, 0) == 0 ?
                   4379:                        execute(t->right->left, 0) :
                   4380:                        execute(t->right->right, 0);
                   4381:                break;
                   4382: 
                   4383:          case TCASE:
                   4384:                cp = evalstr(t->str, 0);
                   4385:                for (t = t->left; t != NULL && t->type == TPAT; t = t->right)
                   4386:                    for (ap = t->vars; *ap; ap++)
                   4387:                        if ((s = evalstr(*ap, DOPAT)) && gmatch(cp, s))
                   4388:                                goto Found;
                   4389:                break;
                   4390:          Found:
                   4391:                rv = execute(t->left, 0);
                   4392:                break;
                   4393: 
                   4394:          case TBRACE:
                   4395:                rv = execute(t->left, 0);
                   4396:                break;
                   4397: 
                   4398:          case TFUNCT:
                   4399:                rv = define(t->str, t->left);
                   4400:                break;
                   4401: 
                   4402:          case TTIME:
                   4403:                rv = timex(t, flags);
                   4404:                break;
                   4405: 
                   4406:          case TEXEC:           /* an eval'd TCOM */
                   4407:                s = t->args[0];
                   4408:                ap = makenv();
                   4409: #ifndef F_SETFD
                   4410:                for (i = 0; i < sizeof(clexec_tab); i++)
                   4411:                  if (clexec_tab[i])
                   4412:                  {
                   4413:                    close(i);
                   4414:                    clexec_tab[i] = 0;
                   4415:                  }
                   4416: #endif
                   4417:                execve(t->str, t->args, ap);
                   4418:                if (errno == ENOEXEC) {
                   4419:                        char *shell;
                   4420: #ifdef SHARPBANG
                   4421:                        scriptexec(t, ap);
                   4422: #else
                   4423:                        shell = strval(global("EXECSHELL"));
                   4424:                        if (shell && *shell) {
                   4425:                                if ((shell = search(shell,path,1)) == NULL)
                   4426:                                        shell = SHELL;
                   4427:                        } else {
                   4428:                                shell = SHELL;
                   4429:                        }
                   4430:                        *t->args-- = t->str;
                   4431:                        *t->args = shell;
                   4432:                        execve(t->args[0], t->args, ap);
                   4433:                        errorf("No shell\n");
                   4434: #endif /* SHARPBANG */
                   4435:                }
                   4436:                errorf("%s: %s\n", s, strerror(errno));
                   4437:        }
                   4438: 
                   4439:        quitenv();              /* restores IO */
                   4440:        if (e.interactive) {    /* flush stdout, shlout */
                   4441:                fflush(shf[1]);
                   4442:                fflush(shf[2]);
                   4443:        }
                   4444:        if ((flags&XEXEC))
                   4445:                exit(rv);       /* exit child */
                   4446:        return rv;
                   4447: }
                   4448: 
                   4449: /*
                   4450:  * execute simple command
                   4451:  */
                   4452: 
                   4453: static int
                   4454: comexec(t, vp, ap, flags)
                   4455:        struct op *t;
                   4456:        register char **ap, **vp;
                   4457:        int flags;
                   4458: {
                   4459:        int i;
                   4460:        int rv = 0;
                   4461:        register char *cp;
                   4462:        register char **lastp;
                   4463:        register struct tbl *tp = NULL;
                   4464:        register struct block *l;
                   4465:        static struct op texec = {TEXEC};
                   4466:        extern int c_exec(), c_builtin();
                   4467: 
                   4468:        if (flag[FXTRACE])
                   4469:                echo(vp, ap);
                   4470: 
                   4471:        /* snag the last argument for $_ */
                   4472:        if ((lastp = ap) && *lastp) {
                   4473:                while (*++lastp)
                   4474:                        ;
                   4475:                setstr(typeset("_",LOCAL,0),*--lastp);
                   4476:        }       
                   4477: 
                   4478:        /* create new variable/function block */
                   4479:        l = (struct block*) alloc(sizeof(struct block), ATEMP);
                   4480:        l->next = e.loc; e.loc = l;
                   4481:        newblock();
                   4482: 
                   4483:  Doexec:
                   4484:        if ((cp = *ap) == NULL)
                   4485:                cp = ":";
                   4486:        tp = findcom(cp, flag[FHASHALL]);
                   4487: 
                   4488:        switch (tp->type) {
                   4489:          case CSHELL:                  /* shell built-in */
                   4490:                while (tp->val.f == c_builtin) {
                   4491:                        if ((cp = *++ap) == NULL)
                   4492:                                break;
                   4493:                        tp = tsearch(&builtins, cp, hash(cp));
                   4494:                        if (tp == NULL)
                   4495:                                errorf("%s: not builtin\n", cp);
                   4496:                }
                   4497:                if (tp->val.f == c_exec) {
                   4498:                        if (*++ap == NULL) {
                   4499:                                e.savefd = NULL; /* don't restore redirection */
                   4500:                                break;
                   4501:                        }
                   4502:                        flags |= XEXEC;
                   4503:                        goto Doexec;
                   4504:                }
                   4505:                if ((tp->flag&TRACE))
                   4506:                        e.loc = l->next; /* no local block */
                   4507:                i = (tp->flag&TRACE) ? 0 : LOCAL;
                   4508:                while (*vp != NULL)
                   4509:                        (void) typeset(*vp++, i, 0);
                   4510:                rv = (*tp->val.f)(ap);
                   4511:                break;
                   4512: 
                   4513:        case CFUNC:                     /* function call */
                   4514:                if (!(tp->flag&ISSET))
                   4515:                        errorf("%s: undefined function\n", cp);
                   4516:                l->argv = ap;
                   4517:                for (i = 0; *ap++ != NULL; i++)
                   4518:                        ;
                   4519:                l->argc = i - 1;
                   4520:                resetopts();
                   4521:                while (*vp != NULL)
                   4522:                        (void) typeset(*vp++, LOCAL, 0);
                   4523:                e.type = E_FUNC;
                   4524:                if (setjmp(e.jbuf))
                   4525:                        rv = exstat; /* return # */
                   4526:                else
                   4527:                        rv = execute(tp->val.t, 0);
                   4528:                break;
                   4529: 
                   4530:        case CEXEC:             /* executable command */
                   4531:                if (!(tp->flag&ISSET)) {
                   4532:                        /*
                   4533:                         * mlj addition:
                   4534:                         *
                   4535:                         * If you specify a full path to a file
                   4536:                         * (or type the name of a file in .) which
                   4537:                         * doesn't have execute priv's, it used to
                   4538:                         * just say "not found".  Kind of annoying,
                   4539:                         * particularly if you just wrote a script
                   4540:                         * but forgot to say chmod 755 script.
                   4541:                         *
                   4542:                         * This should probably be done in eaccess(),
                   4543:                         * but it works here (at least I haven't noticed
                   4544:                         * changing errno here breaking something
                   4545:                         * else).
                   4546:                         *
                   4547:                         * So, we assume that if the file exists, it
                   4548:                         * doesn't have execute privs; else, it really
                   4549:                         * is not found.
                   4550:                         */
                   4551:                        if (access(cp, 0) < 0)
                   4552:                            shellf("%s: not found\n", cp);
                   4553:                        else
                   4554:                            shellf("%s: cannot execute\n", cp);
                   4555:                        rv = 1;
                   4556:                        break;
                   4557:                }
                   4558: 
                   4559:                /* set $_ to program's full path */
                   4560:                setstr(typeset("_", LOCAL|EXPORT, 0), tp->val.s);
                   4561:                while (*vp != NULL)
                   4562:                        (void) typeset(*vp++, LOCAL|EXPORT, 0);
                   4563: 
                   4564:                if ((flags&XEXEC)) {
                   4565:                        j_exit();
                   4566:                        if (flag[FMONITOR] || !(flags&XBGND))
                   4567:                        {
                   4568: #ifdef USE_SIGACT
                   4569:                          sigaction(SIGINT, &Sigact_dfl, NULL);
                   4570:                          sigaction(SIGQUIT, &Sigact_dfl, NULL);
                   4571: #else
                   4572:                          signal(SIGINT, SIG_DFL);
                   4573:                          signal(SIGQUIT, SIG_DFL);
                   4574: #endif
                   4575:                        }
                   4576:                }
                   4577: 
                   4578:                /* to fork we set up a TEXEC node and call execute */
                   4579:                texec.left = t; /* for tprint */
                   4580:                texec.str = tp->val.s;
                   4581:                texec.args = ap;
                   4582:                rv = exchild(&texec, flags);
                   4583:                break;
                   4584:        }
                   4585:        if (rv != 0 && flag[FERREXIT])
                   4586:                leave(rv);
                   4587:        return (exstat = rv);
                   4588: }
                   4589: 
                   4590: #ifdef SHARPBANG
                   4591: static void
                   4592: scriptexec(tp, ap)
                   4593:        register struct op *tp;
                   4594:        register char **ap;
                   4595: {
                   4596:        char line[LINE];
                   4597:        register char *cp;
                   4598:        register int fd, n;
                   4599:        char *shell;
                   4600: 
                   4601:        shell = strval(global("EXECSHELL"));
                   4602:        if (shell && *shell) {
                   4603:                if ((shell = search(shell,path,1)) == NULL)
                   4604:                        shell = SHELL;
                   4605:        } else {
                   4606:                shell = SHELL;
                   4607:        }
                   4608: 
                   4609:        *tp->args-- = tp->str;
                   4610:        line[0] = '\0';
                   4611:        if ((fd = open(tp->str,0)) >= 0) {
                   4612:                if ((n = read(fd, line, LINE - 1)) > 0)
                   4613:                        line[n] = '\0';
                   4614:                (void) close(fd);
                   4615:        }
                   4616:        if (line[0] == '#' && line[1] == '!') {
                   4617:                cp = &line[2];
                   4618:                while (*cp && (*cp == ' ' || *cp == '\t'))
                   4619:                        cp++;
                   4620:                if (*cp && *cp != '\n') {
                   4621:                        *tp->args = cp;
                   4622:                        while (*cp && *cp != '\n' && *cp != ' ' && *cp != '\t')
                   4623:                                cp++;
                   4624:                        if (*cp && *cp != '\n') {
                   4625:                                *cp++ = '\0';
                   4626:                                while (*cp && (*cp == ' ' || *cp == '\t'))
                   4627:                                        cp++;
                   4628:                                if (*cp && *cp != '\n') {
                   4629:                                        tp->args--;
                   4630:                                        tp->args[0] = tp->args[1];
                   4631:                                        tp->args[1] = cp;
                   4632:                                        while (*cp && *cp != '\n' &&
                   4633:                                               *cp != ' ' && *cp != '\t')
                   4634:                                                cp++;
                   4635:                                }
                   4636:                        }
                   4637:                        *cp = '\0';
                   4638:                } else
                   4639:                        *tp->args = shell;
                   4640:        } else
                   4641:                *tp->args = shell;
                   4642: 
                   4643:        (void) execve(tp->args[0], tp->args, ap);
                   4644:        errorf( "No shell\n" );
                   4645: }
                   4646: #endif /* SHARPBANG */
                   4647: 
                   4648: int
                   4649: shcomexec(wp)
                   4650:        register char **wp;
                   4651: {
                   4652:        register struct tbl *tp;
                   4653: 
                   4654:        tp = tsearch(&builtins, *wp, hash(*wp));
                   4655:        if (tp == NULL)
                   4656:                errorf("%s: shcomexec botch\n", *wp);
                   4657:        return (*tp->val.f)(wp);
                   4658: }
                   4659: 
                   4660: /*
                   4661:  * define function
                   4662:  */
                   4663: int
                   4664: define(name, t)
                   4665:        char    *name;
                   4666:        struct op *t;
                   4667: {
                   4668:        register struct block *l;
                   4669:        register struct tbl *tp;
                   4670: 
                   4671:        for (l = e.loc; l != NULL; l = l->next) {
                   4672:                lastarea = &l->area;
                   4673:                tp = tsearch(&l->funs, name, hash(name));
                   4674:                if (tp != NULL && (tp->flag&DEFINED))
                   4675:                        break;
                   4676:                if (l->next == NULL) {
                   4677:                        tp = tenter(&l->funs, name, hash(name));
                   4678:                        tp->flag = DEFINED|FUNCT;
                   4679:                        tp->type = CFUNC;
                   4680:                }
                   4681:        }
                   4682: 
                   4683:        if ((tp->flag&ALLOC))
                   4684:                tfree(tp->val.t, lastarea);
                   4685:        tp->flag &= ~(ISSET|ALLOC);
                   4686: 
                   4687:        if (t == NULL) {                /* undefine */
                   4688:                tdelete(tp);
                   4689:                return 0;
                   4690:        }
                   4691: 
                   4692:        tp->val.t = tcopy(t, lastarea);
                   4693:        tp->flag |= (ISSET|ALLOC);
                   4694: 
                   4695:        return 0;
                   4696: }
                   4697: 
                   4698: /*
                   4699:  * add builtin
                   4700:  */
                   4701: builtin(name, func)
                   4702:        char *name;
                   4703:        int (*func)();
                   4704: {
                   4705:        register struct tbl *tp;
                   4706:        int flag = DEFINED;
                   4707: 
                   4708:        if (*name == '=') {             /* sets keyword variables */
                   4709:                name++;
                   4710:                flag |= TRACE;  /* command does variable assignment */
                   4711:        }
                   4712: 
                   4713:        tp = tenter(&builtins, name, hash(name));
                   4714:        tp->flag |= flag;
                   4715:        tp->type = CSHELL;
                   4716:        tp->val.f = func;
                   4717: }
                   4718: 
                   4719: /*
                   4720:  * find command
                   4721:  * either function, hashed command, or built-in (in that order)
                   4722:  */
                   4723: struct tbl *
                   4724: findcom(name, insert)
                   4725:        char    *name;
                   4726:        int     insert;                 /* insert if not found */
                   4727: {
                   4728:        register struct block *l = e.loc;
                   4729:        unsigned int h = hash(name);
                   4730:        register struct tbl *tp = NULL;
                   4731:        static struct tbl temp;
                   4732: 
                   4733:        if (strchr(name, '/') != NULL) {
                   4734:                tp = &temp;
                   4735:                tp->type = CEXEC;
                   4736:                tp->flag = 0;   /* make ~ISSET */
                   4737:                goto Search;
                   4738:        }
                   4739:        for (l = e.loc; l != NULL; l = l->next) {
                   4740:                tp = tsearch(&l->funs, name, h);
                   4741:                if (tp != NULL && (tp->flag&DEFINED))
                   4742:                        break;
                   4743:        }
                   4744:        if (tp == NULL) {
                   4745:                tp = tsearch(&commands, name, h);
                   4746:                if (tp != NULL && eaccess(tp->val.s,1) != 0) {
                   4747:                        if (tp->flag&ALLOC)
                   4748:                                afree(tp->val.s, commands.areap);
                   4749:                        tp->type = CEXEC;
                   4750:                        tp->flag = DEFINED;
                   4751:                }
                   4752:        }
                   4753:        if (tp == NULL)
                   4754:                tp = tsearch(&builtins, name, h);
                   4755:        if (tp == NULL) {
                   4756:                tp = tenter(&commands, name, h);
                   4757:                tp->type = CEXEC;
                   4758:                tp->flag = DEFINED;
                   4759:        }
                   4760:   Search:
                   4761:        if (tp->type == CEXEC && !(tp->flag&ISSET)) {
                   4762:                if (!insert) {
                   4763:                        tp = &temp;
                   4764:                        tp->type = CEXEC;
                   4765:                        tp->flag = 0;   /* make ~ISSET */
                   4766:                }
                   4767:                name = search(name, path, 1);
                   4768:                if (name != NULL) {
                   4769:                        tp->val.s = strsave(name,
                   4770:                                            (tp == &temp) ? ATEMP : APERM);
                   4771:                        tp->flag |= ISSET|ALLOC;
                   4772:                }
                   4773:        }
                   4774:        return tp;
                   4775: }
                   4776: 
                   4777: /*
                   4778:  * flush executable commands with relative paths
                   4779:  */
                   4780: flushcom(all)
                   4781:        int all;                /* just relative or all */
                   4782: {
                   4783:        register struct tbl *tp;
                   4784: 
                   4785:        for (twalk(&commands); (tp = tnext()) != NULL; )
                   4786:                if ((tp->flag&ISSET) && (all || tp->val.s[0] != '/')) {
                   4787:                        if ((tp->flag&ALLOC))
                   4788:                                afree(tp->val.s, commands.areap);
                   4789:                        tp->flag = DEFINED; /* make ~ISSET */
                   4790:                }
                   4791: }
                   4792: 
                   4793: /*
                   4794:  * search for command with PATH
                   4795:  */
                   4796: char *
                   4797: search(name, path, mode)
                   4798:        char *name, *path;
                   4799:        int mode;               /* 0: readable; 1: executable */
                   4800: {
                   4801:        register int i;
                   4802:        register char *sp, *tp;
                   4803:        struct stat buf;
                   4804: 
                   4805:        if (strchr(name, '/'))
                   4806:                return (eaccess(name, mode) == 0) ? name : NULL;
                   4807: 
                   4808:        sp = path;
                   4809:        while (sp != NULL) {
                   4810:                tp = line;
                   4811:                for (; *sp != '\0'; tp++)
                   4812:                        if ((*tp = *sp++) == ':') {
                   4813:                                --sp;
                   4814:                                break;
                   4815:                        }
                   4816:                if (tp != line)
                   4817:                        *tp++ = '/';
                   4818:                for (i = 0; (*tp++ = name[i++]) != '\0';)
                   4819:                        ;
                   4820:                i = eaccess(line, mode);
                   4821:                if (i == 0 && (mode != 1 || (stat(line,&buf) == 0 &&
                   4822:                    (buf.st_mode & S_IFMT) == S_IFREG)))
                   4823:                        return line;
                   4824:                /* what should we do about EACCES? */
                   4825:                if (*sp++ == '\0')
                   4826:                        sp = NULL;
                   4827:        }
                   4828:        return NULL;
                   4829: }
                   4830: 
                   4831: /*
                   4832:  * set up redirection, saving old fd's in e.savefd
                   4833:  */
                   4834: static void
                   4835: iosetup(iop)
                   4836:        register struct ioword *iop;
                   4837: {
                   4838:        register int u = -1;
                   4839:        char *cp = iop->name;
                   4840:        extern long lseek();
                   4841: 
                   4842:        if (iop->unit == 0 || iop->unit == 1 || iop->unit == 2)
                   4843:                e.interactive = 0;
                   4844: #if 0
                   4845:        if (e.savefd[iop->unit] != 0)
                   4846:                errorf("file descriptor %d already redirected\n", iop->unit);
                   4847: #endif
                   4848:        e.savefd[iop->unit] = savefd(iop->unit);
                   4849: 
                   4850:        if ((iop->flag&IOTYPE) != IOHERE)
                   4851:                cp = evalonestr(cp, DOTILDE|DOGLOB);
                   4852: 
                   4853:        switch (iop->flag&IOTYPE) {
                   4854:          case IOREAD:
                   4855:                u = open(cp, 0);
                   4856:                break;
                   4857: 
                   4858:          case IOCAT:
                   4859:                if ((u = open(cp, 1)) >= 0) {
                   4860:                        (void) lseek(u, (long)0, 2);
                   4861:                        break;
                   4862:                }
                   4863:                /* FALLTHROUGH */
                   4864:          case IOWRITE:
                   4865:                u = creat(cp, 0666);
                   4866:                break;
                   4867: 
                   4868:          case IORDWR:
                   4869:                u = open(cp, 2);
                   4870:                break;
                   4871: 
                   4872:          case IOHERE:
                   4873:                u = herein(cp, iop->flag&IOEVAL);
                   4874:                /* cp may have wrong name */
                   4875:                break;
                   4876: 
                   4877:          case IODUP:
                   4878:                if (*cp == '-')
                   4879:                        close(u = iop->unit);
                   4880:                else
                   4881:                if (digit(*cp))
                   4882:                        u = *cp - '0';
                   4883:                else
                   4884:                        errorf("%s: illegal >& argument\n", cp);
                   4885:                break;
                   4886:        }
                   4887:        if (u < 0)
                   4888:                errorf("%s: cannot %s\n", cp,
                   4889:                       (iop->flag&IOTYPE) == IOWRITE ? "create" : "open");
                   4890:        if (u != iop->unit) {
                   4891:                (void) dup2(u, iop->unit);
                   4892:                if (iop->flag != IODUP)
                   4893:                        close(u);
                   4894:        }
                   4895: 
                   4896:        fopenshf(iop->unit);
                   4897: }
                   4898: 
                   4899: /*
                   4900:  * open here document temp file.
                   4901:  * if unquoted here, expand here temp file into second temp file.
                   4902:  */
                   4903: static int
                   4904: herein(hname, sub)
                   4905:        char *hname;
                   4906:        int sub;
                   4907: {
                   4908:        int fd;
                   4909:        FILE * volatile f = NULL;
                   4910: 
                   4911:        f = fopen(hname, "r");
                   4912:        if (f == NULL)
                   4913:                return -1;
                   4914:        setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
                   4915: 
                   4916:        if (sub) {
                   4917:                char *cp;
                   4918:                struct source *s;
                   4919:                struct temp *h;
                   4920: 
                   4921:                newenv(E_ERRH);
                   4922:                if (setjmp(e.jbuf)) {
                   4923:                        if (f != NULL)
                   4924:                                fclose(f);
                   4925:                        quitenv();
                   4926:                        return -1; /* todo: error()? */
                   4927:                }
                   4928: 
                   4929:                /* set up yylex input from here file */
                   4930:                s = pushs(SFILE);
                   4931:                s->u.file = f;
                   4932:                source = s;
                   4933:                if (yylex(ONEWORD) != LWORD)
                   4934:                        errorf("exec:herein error\n");
                   4935:                cp = evalstr(yylval.cp, 0);
                   4936: 
                   4937:                /* write expanded input to another temp file */
                   4938:                h = maketemp(ATEMP);
                   4939:                h->next = e.temps; e.temps = h;
                   4940:                if (h == NULL)
                   4941:                        error();
                   4942:                f = fopen(h->name, "w+");
                   4943:                if (f == NULL)
                   4944:                        error();
                   4945:                setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
                   4946:                fputs(cp, f);
                   4947:                rewind(f);
                   4948: 
                   4949:                quitenv();
                   4950:        }
                   4951:        fd = dup(fileno(f));
                   4952:        fclose(f);
                   4953:        return fd;
                   4954: }
                   4955: 
                   4956: static void
                   4957: echo(vp, ap)
                   4958:        register char **vp, **ap;
                   4959: {
                   4960:        shellf("+");
                   4961:        while (*vp != NULL)
                   4962:                shellf(" %s", *vp++);
                   4963:        while (*ap != NULL)
                   4964:                shellf(" %s", *ap++);
                   4965:        shellf("\n");
                   4966: }
                   4967: 
                   4968: /*
                   4969:  *     ksh special - the select command processing section
                   4970:  *     print the args in column form - assuming that we can
                   4971:  */
                   4972: #define        COLARGS         20
                   4973: 
                   4974: static char *
                   4975: do_selectargs(ap, secondtime)
                   4976:        register char **ap;
                   4977:        char    *secondtime;
                   4978: {
                   4979:        char *rv;
                   4980: 
                   4981:        register int i, c;
                   4982:        static char *replybase = NULL;
                   4983:        static int replymax;
                   4984:        static int repct;
                   4985:        static int argct;
                   4986:        
                   4987:        /*
                   4988:         * deal with REPLY variable
                   4989:         */
                   4990:        if (replybase == NULL) {
                   4991:                replybase = alloc(64, APERM);
                   4992:                replymax = 64;
                   4993:        }
                   4994: 
                   4995:        if (!secondtime)
                   4996:                argct = pr_menu(ap, 0);
                   4997:        
                   4998:        /*
                   4999:         * and now ask for an answer
                   5000:         */
                   5001: retry:
                   5002:        shellf("%s", strval(global("PS3")));
                   5003:        fflush(shlout);
                   5004:        repct = 0;
                   5005:        i = 0;
                   5006:        rv = NULL;
                   5007:        while ((c = selread()) != EOF) {
                   5008:                if (c == -2) {
                   5009:                        shellf("Read error\n");
                   5010:                        rv = (char*)1;
                   5011:                        break;
                   5012:                }
                   5013:                if (repct+1 >= replymax)
                   5014:                {       replymax += 64;
                   5015:                        replybase = aresize(replybase, replymax, APERM);
                   5016:                }
                   5017:                if (i >= 0 && c >= '0' && c <= '9') {
                   5018:                        replybase[repct++] = c;
                   5019:                        if (i >= 0)
                   5020:                                i = i*10 + (c - '0');
                   5021:                }
                   5022:                else
                   5023:                if (c == '\n') {
                   5024:                        if (repct == 0) {
                   5025:                                pr_menu(ap, 1);
                   5026:                                goto retry;
                   5027:                        }
                   5028:                                
                   5029:                        if (i >= 1 && i <= argct)
                   5030:                                rv = ap[i-1];
                   5031:                        else    rv = "";
                   5032:                        break;
                   5033:                } else
                   5034:                        i = -1, replybase[repct++] = c;
                   5035:        }
                   5036:        if (rv == NULL) {
                   5037:                shellf("\n");
                   5038:                rv = (char *)1;
                   5039:        }
                   5040:        replybase[repct] = '\0';
                   5041:        setstr(global("REPLY"), replybase);
                   5042:        return rv;
                   5043: }
                   5044: 
                   5045: /*
                   5046:  *     print a select style menu
                   5047:  */
                   5048: int
                   5049: pr_menu(ap, usestored)
                   5050:        register char **ap;
                   5051:        int usestored;
                   5052: {
                   5053:        register char **pp;
                   5054:        register i, j;
                   5055:        register int ix;
                   5056:        static int argct;
                   5057:        static int nwidth;
                   5058:        static int dwidth;
                   5059:        static int ncols;
                   5060:        static int nrows;
                   5061: 
                   5062:        if (usestored == 0) {
                   5063:                /*
                   5064:                 * get dimensions of the list
                   5065:                 */
                   5066:                for (argct = 0, nwidth = 0, pp = ap; *pp; argct++, pp++) {
                   5067:                        i = strlen(*pp);
                   5068:                        nwidth = (i > nwidth) ? i : nwidth;
                   5069:                }
                   5070:                /*
                   5071:                 * we will print an index of the form
                   5072:                 *      %d)
                   5073:                 * in front of each entry
                   5074:                 * get the max width of this
                   5075:                 */
                   5076:                for (i = argct, dwidth = 1; i >= 10; i /= 10)
                   5077:                        dwidth++;
                   5078: 
                   5079:                if (argct < COLARGS)
                   5080:                        ncols = 1, nrows = argct;
                   5081:                else {
                   5082:                        ncols = x_cols/(nwidth+dwidth+3);
                   5083:                        nrows = argct/ncols;
                   5084:                        if (argct%ncols) nrows++;
                   5085:                        if (ncols > nrows)
                   5086:                        i = nrows, nrows = ncols, ncols = 1;
                   5087:                }
                   5088: 
                   5089:        }
                   5090:        /*
                   5091:         * display the menu
                   5092:         */
                   5093:        for (i = 0; i < nrows; i++) {
                   5094:                for (j = 0; j < ncols; j++) {
                   5095:                        ix = j*nrows + i;
                   5096:                        if (ix < argct)
                   5097:                                shellf("%*d) %-*.*s ", dwidth, ix+1, nwidth, nwidth, ap[ix]);
                   5098:                        }
                   5099:                shellf("\n");
                   5100:        }
                   5101:        return argct;
                   5102: }
                   5103: 
                   5104: static int
                   5105: selread()
                   5106: {      char c;
                   5107:        register int    rv;
                   5108:        
                   5109:        switch (read(0, &c, 1)) {
                   5110:           case 1:
                   5111:                rv = c&0xff;
                   5112:                break;
                   5113:           case 0:
                   5114:                rv = EOF;
                   5115:                break;
                   5116:           case -1:
                   5117:                rv = -2;
                   5118:                break;
                   5119:        }
                   5120:        return rv;
                   5121: }
                   5122: ./pdksh/sh/vi.c   644    653   1762       75042  5243743671  10640 0ustar  hlu/*
                   5123:  *     vi command editing
                   5124:  *     written by John Rochester (initially for nsh)
                   5125:  *     bludgeoned to fit PD ksh by Larry Bouzane and Eric Gisin
                   5126:  *     Further hacked (bugfixes and tweaks) by Mike Jetzer
                   5127:  */
                   5128: 
                   5129: #include "config.h"
                   5130: #ifdef VI
                   5131: 
                   5132: #ifndef lint
                   5133: static char *RCSid = "$Id: vi.c,v 1.3 1992/08/10 12:03:31 sjg Exp $";
                   5134: #endif
                   5135: 
                   5136: #include "stdh.h"
                   5137: #include <unistd.h>
                   5138: #include <signal.h>
                   5139: #include <fcntl.h>
                   5140: #include <ctype.h>
                   5141: #include <errno.h>
                   5142: #include <setjmp.h>
                   5143: #include "sh.h"
                   5144: #include "expand.h"
                   5145: #include "edit.h"
                   5146: 
                   5147: #define CMDLEN         256
                   5148: #define Ctrl(c)                (c&0x1f)
                   5149: extern int     histN();
                   5150: 
                   5151: static int      nextstate   ARGS((int ch));
                   5152: static int      vi_insert   ARGS((int ch));
                   5153: static int      vi_cmd      ARGS((int argcnt, char *cmd));
                   5154: static int      domove      ARGS((int argcnt, char *cmd, int sub));
                   5155: static int      redo_insert ARGS((int count));
                   5156: static          yank_range  ARGS((int a, int b));
                   5157: static int      bracktype   ARGS((int ch));
                   5158: static          edit_reset  ARGS((char *buf, int len));
                   5159: static int      putbuf      ARGS((char *buf, int len, int repl));
                   5160: static          stripblanks ARGS((void));
                   5161: static          del_range   ARGS((int a, int b));
                   5162: static int      findch      ARGS((int ch, int cnt, int forw, int incl));
                   5163: static int      forwword    ARGS((int argcnt));
                   5164: static int      backword    ARGS((int argcnt));
                   5165: static int      endword     ARGS((int argcnt));
                   5166: static int      Forwword    ARGS((int argcnt));
                   5167: static int      Backword    ARGS((int argcnt));
                   5168: static int      Endword     ARGS((int argcnt));
                   5169: static int      grabhist    ARGS((int save, int n));
                   5170: static int      grabsearch  ARGS((int save, int start, int fwd, char *pat));
                   5171: static          redraw_line ARGS((void));
                   5172: static          refresh     ARGS((int leftside));
                   5173: static int      outofwin    ARGS((void));
                   5174: static          rewindow    ARGS((void));
                   5175: static int      newcol      ARGS((int ch, int col));
                   5176: static          display     ARGS((char *wb1, char *wb2, int leftside));
                   5177: static          ed_mov_opt  ARGS((int col, char *wb));
                   5178: 
                   5179: #define C_     0x1
                   5180: #define M_     0x2
                   5181: #define E_     0x4
                   5182: #define X_     0x8
                   5183: #define U_     0x10
                   5184: #define B_     0x20
                   5185: #define O_     0x40
                   5186: #define S_     0x80
                   5187: 
                   5188: #define isbad(c)       (classify[c]&B_)
                   5189: #define iscmd(c)       (classify[c]&(M_|E_|C_|U_))
                   5190: #define ismove(c)      (classify[c]&M_)
                   5191: #define isextend(c)    (classify[c]&E_)
                   5192: #define islong(c)      (classify[c]&X_)
                   5193: #define ismeta(c)      (classify[c]&O_)
                   5194: #define isundoable(c)  (!(classify[c]&U_))
                   5195: #define issrch(c)      (classify[c]&S_)
                   5196: 
                   5197: char   classify[128] = {
                   5198:        B_,     0,      0,      0,      0,      0,      O_,     0,
                   5199: #if 1  /* Mike B. changes */
                   5200:        C_|M_,  0,      O_,     0,      O_,     O_,     O_,     0,
                   5201: #else
                   5202:        C_,     0,      O_,     0,      O_,     O_,     O_,     0,
                   5203: #endif
                   5204:        O_,     0,      C_|U_,  0,      0,      0,      0,      0,
                   5205:        0,      0,      O_,     0,      0,      0,      0,      0,
                   5206: #if 1  /* Mike B. changes */
                   5207:        C_|M_,  0,      0,      C_,     M_,     C_,     0,      0,
                   5208: #else
                   5209:        C_,     0,      0,      C_,     M_,     C_,     0,      0,
                   5210: #endif
                   5211:        0,      0,      C_,     C_,     M_,     C_,     0,      C_|S_,
                   5212:        M_,     0,      0,      0,      0,      0,      0,      0,
                   5213:        0,      0,      0,      M_,     0,      C_,     0,      C_|S_,
                   5214:        0,      C_,     M_,     C_,     C_,     M_,     M_|X_,  C_,
                   5215:        0,      C_,     0,      0,      0,      0,      C_,     0,
                   5216:        C_,     0,      C_,     C_,     M_|X_,  0,      0,      M_,
                   5217:        C_,     C_,     0,      0,      0,      0,      M_,     C_,
                   5218:        0,      C_,     M_,     E_,     E_,     M_,     M_|X_,  0,
                   5219:        M_,     C_,     C_,     C_,     M_,     0,      C_,     0,
                   5220:        C_,     0,      C_,     C_,     M_|X_,  C_|U_,  0,      M_,
                   5221:        C_,     E_,     0,      0,      0,      0,      C_,     0
                   5222: };
                   5223: 
                   5224: #define MAXVICMD       3
                   5225: #define SRCHLEN                40
                   5226: 
                   5227: #define INSERT         1
                   5228: #define REPLACE                2
                   5229: 
                   5230: #define VNORMAL                0
                   5231: #define VARG1          1
                   5232: #define VEXTCMD                2
                   5233: #define VARG2          3
                   5234: #define VXCH           4
                   5235: #define VFAIL          5
                   5236: #define VCMD           6
                   5237: #define VREDO          7
                   5238: #define VLIT           8
                   5239: #define VSEARCH                9
                   5240: #define VREPLACE1CHAR  10
                   5241: 
                   5242: struct edstate {
                   5243:        int     winleft;
                   5244:        char    *cbuf;
                   5245:        int     cbufsize;
                   5246:        int     linelen;
                   5247:        int     cursor;
                   5248: };
                   5249: 
                   5250: static char            undocbuf[CMDLEN];
                   5251: 
                   5252: static struct edstate  ebuf;
                   5253: static struct edstate  undobuf = { 0, undocbuf, CMDLEN, 0, 0 };
                   5254: 
                   5255: static struct edstate  *es;                    /* current editor state */
                   5256: static struct edstate  *undo;
                   5257: 
                   5258: static char    ibuf[CMDLEN];           /* input buffer */
                   5259: static int     inslen;                 /* length of input buffer */
                   5260: static int     srchlen;                /* length of current search pattern */
                   5261: static char    ybuf[CMDLEN];           /* yank buffer */
                   5262: static int     yanklen;                /* length of yank buffer */
                   5263: static int     fsavecmd = ' ';         /* last find command */
                   5264: static int     fsavech;                /* character to find */
                   5265: static char    lastcmd[MAXVICMD];      /* last non-move command */
                   5266: static int     lastac;                 /* argcnt for lastcmd */
                   5267: static int     lastsearch = ' ';       /* last search command */
                   5268: static char    srchpat[SRCHLEN];       /* last search pattern */
                   5269: static int     insert;                 /* non-zero in insert mode */
                   5270: static int     hnum;                   /* position in history */
                   5271: static int     hlast;                  /* 1 past last position in history */
                   5272: static int     modified;               /* buffer has been "modified" */
                   5273: static int     state;
                   5274: 
                   5275: #if 0
                   5276: vi_init()
                   5277: {
                   5278:        es = (struct edstate *) malloc((unsigned) sizeof(struct edstate));
                   5279:        fsavecmd = ' ';
                   5280:        lastsearch = ' ';
                   5281: }
                   5282: 
                   5283: edit_init()
                   5284: {
                   5285:        wbuf[0] = malloc((unsigned) (x_cols - 3));
                   5286:        wbuf[1] = malloc((unsigned) (x_cols - 3));
                   5287: }
                   5288: #endif
                   5289: 
                   5290: void
                   5291: vi_reset(buf, len)
                   5292:        char    *buf;
                   5293:        int     len;
                   5294: {
                   5295:        state = VNORMAL;
                   5296:        hnum = hlast = histnum(-1) + 1;
                   5297:        insert = INSERT;
                   5298:        yanklen = 0;
                   5299:        inslen = 0;
                   5300:        lastcmd[0] = 'a';
                   5301:        lastac = 1;
                   5302:        modified = 1;
                   5303:        edit_reset(buf, len);
                   5304: }
                   5305: 
                   5306: int
                   5307: vi_hook(ch)
                   5308:        int             ch;
                   5309: {
                   5310:        static char     curcmd[MAXVICMD];
                   5311:        static char     locpat[SRCHLEN];
                   5312:        static int      cmdlen;
                   5313:        static int      argc1, argc2;
                   5314: 
                   5315:        if (state != VSEARCH && (ch == '\r' || ch == '\n')) {
                   5316:                x_putc('\r');
                   5317:                x_putc('\n');
                   5318:                x_flush();
                   5319:                return 1;
                   5320:        }
                   5321: 
                   5322:        switch (state) {
                   5323: 
                   5324:        case VREPLACE1CHAR:
                   5325:                curcmd[cmdlen++] = ch;
                   5326:                state = VCMD;
                   5327:                break;
                   5328: 
                   5329:        case VNORMAL:
                   5330:                if (insert != 0) {
                   5331:                        if (ch == Ctrl('v')) {
                   5332:                                state = VLIT;
                   5333:                                ch = '^';
                   5334:                        }
                   5335:                        if (vi_insert(ch) != 0) {
                   5336:                                x_putc(Ctrl('g'));
                   5337:                                state = VNORMAL;
                   5338:                        } else {
                   5339:                                if (state == VLIT) {
                   5340:                                        es->cursor--;
                   5341:                                        refresh(0);
                   5342:                                } else
                   5343:                                        refresh(insert != 0);
                   5344:                        }
                   5345:                } else {
                   5346:                        cmdlen = 0;
                   5347:                        argc1 = 0;
                   5348:                        if (ch >= '1' && ch <= '9') {
                   5349:                                argc1 = ch - '0';
                   5350:                                state = VARG1;
                   5351:                        } else {
                   5352:                                curcmd[cmdlen++] = ch;
                   5353:                                state = nextstate(ch);
                   5354:                                if (state == VSEARCH) {
                   5355:                                        save_cbuf();
                   5356:                                        es->cursor = 0;
                   5357:                                        es->linelen = 0;
                   5358:                                        if (ch == '/') {
                   5359:                                                if (putbuf("/", 1, 0) != 0) {
                   5360:                                                        return -1;
                   5361:                                                }
                   5362:                                        } else if (putbuf("?", 1, 0) != 0) 
                   5363:                                                        return -1;
                   5364:                                        refresh(0);
                   5365:                                }
                   5366:                        }
                   5367:                }
                   5368:                break;
                   5369: 
                   5370:        case VLIT:
                   5371:                if (isbad(ch)) {
                   5372:                        del_range(es->cursor, es->cursor + 1);
                   5373:                        x_putc(Ctrl('g'));
                   5374:                } else
                   5375:                        es->cbuf[es->cursor++] = ch;
                   5376:                refresh(1);
                   5377:                state = VNORMAL;
                   5378:                break;
                   5379: 
                   5380:        case VARG1:
                   5381:                if (isdigit(ch))
                   5382:                        argc1 = argc1 * 10 + ch - '0';
                   5383:                else {
                   5384:                        curcmd[cmdlen++] = ch;
                   5385:                        state = nextstate(ch);
                   5386:                }
                   5387:                break;
                   5388: 
                   5389:        case VEXTCMD:
                   5390:                argc2 = 0;
                   5391:                if (ch >= '1' && ch <= '9') {
                   5392:                        argc2 = ch - '0';
                   5393:                        state = VARG2;
                   5394:                        return 0;
                   5395:                } else {
                   5396:                        curcmd[cmdlen++] = ch;
                   5397:                        if (ch == curcmd[0])
                   5398:                                state = VCMD;
                   5399:                        else if (ismove(ch))
                   5400:                                state = nextstate(ch);
                   5401:                        else
                   5402:                                state = VFAIL;
                   5403:                }
                   5404:                break;
                   5405: 
                   5406:        case VARG2:
                   5407:                if (isdigit(ch))
                   5408:                        argc2 = argc2 * 10 + ch - '0';
                   5409:                else {
                   5410:                        if (argc1 == 0)
                   5411:                                argc1 = argc2;
                   5412:                        else
                   5413:                                argc1 *= argc2;
                   5414:                        curcmd[cmdlen++] = ch;
                   5415:                        if (ch == curcmd[0])
                   5416:                                state = VCMD;
                   5417:                        else if (ismove(ch))
                   5418:                                state = nextstate(ch);
                   5419:                        else
                   5420:                                state = VFAIL;
                   5421:                }
                   5422:                break;
                   5423: 
                   5424:        case VXCH:
                   5425:                if (ch == Ctrl('['))
                   5426:                        state = VNORMAL;
                   5427:                else {
                   5428:                        curcmd[cmdlen++] = ch;
                   5429:                        state = VCMD;
                   5430:                }
                   5431:                break;
                   5432: 
                   5433:        case VSEARCH:
                   5434:                switch (ch) {
                   5435: 
                   5436:                /* case Ctrl('['): */
                   5437:                case '\r':
                   5438:                case '\n':
                   5439:                        locpat[srchlen] = '\0';
                   5440:                        (void) strcpy(srchpat, locpat);
                   5441:                        /* redraw_line(); */
                   5442:                        state = VCMD;
                   5443:                        break;
                   5444: 
                   5445:                case 0x7f:
                   5446:                        if (srchlen == 0) {
                   5447:                                restore_cbuf();
                   5448:                                state = VNORMAL;
                   5449:                        } else {
                   5450:                                srchlen--;
                   5451:                                if (locpat[srchlen] < ' ' ||
                   5452:                                                locpat[srchlen] == 0x7f) {
                   5453:                                        es->linelen--;
                   5454:                                }
                   5455:                                es->linelen--;
                   5456:                                es->cursor = es->linelen;
                   5457:                                refresh(0);
                   5458:                                return 0;
                   5459:                        }
                   5460:                        refresh(0);
                   5461:                        break;
                   5462: 
                   5463:                case Ctrl('u'):
                   5464:                        srchlen = 0;
                   5465:                        es->linelen = 1;
                   5466:                        es->cursor = 1;
                   5467:                        refresh(0);
                   5468:                        return 0;
                   5469: 
                   5470:                default:
                   5471:                        if (srchlen == SRCHLEN - 1)
                   5472:                                x_putc(Ctrl('g'));
                   5473:                        else {
                   5474:                                locpat[srchlen++] = ch;
                   5475:                                if (ch < ' ' || ch == 0x7f) {
                   5476:                                        es->cbuf[es->linelen++] = '^';
                   5477:                                        es->cbuf[es->linelen++] = ch ^ '@';
                   5478:                                } else
                   5479:                                        es->cbuf[es->linelen++] = ch;
                   5480:                                es->cursor = es->linelen;
                   5481:                                refresh(0);
                   5482:                        }
                   5483:                        return 0;
                   5484:                        break;
                   5485:                }
                   5486:                break;
                   5487:        }
                   5488:        switch (state) {
                   5489: 
                   5490:        case VCMD:
                   5491:                state = VNORMAL;
                   5492:                switch (vi_cmd(argc1, curcmd)) {
                   5493:                case -1:
                   5494:                        x_putc(Ctrl('g'));
                   5495:                        break;
                   5496:                case 0:
                   5497:                        if (insert != 0)
                   5498:                                inslen = 0;
                   5499:                        refresh(insert != 0);
                   5500:                        break;
                   5501:                case 1:
                   5502:                        refresh(0);
                   5503:                        x_putc('\r');
                   5504:                        x_putc('\n');
                   5505:                        x_flush();
                   5506:                        return 1;
                   5507:                }
                   5508:                break;
                   5509: 
                   5510:        case VREDO:
                   5511:                state = VNORMAL;
                   5512:                if (argc1 != 0)
                   5513:                        lastac = argc1;
                   5514:                switch (vi_cmd(lastac, lastcmd) != 0) {
                   5515:                case -1:
                   5516:                        x_putc(Ctrl('g'));
                   5517:                        refresh(0);
                   5518:                        break;
                   5519:                case 0:
                   5520:                        if (insert != 0) {
                   5521:                                if (lastcmd[0] == 's' || lastcmd[0] == 'c' ||
                   5522:                                                lastcmd[0] == 'C') {
                   5523:                                        if (redo_insert(1) != 0)
                   5524:                                                x_putc(Ctrl('g'));
                   5525:                                } else {
                   5526:                                        if (redo_insert(lastac) != 0)
                   5527:                                                x_putc(Ctrl('g'));
                   5528:                                }
                   5529:                        }
                   5530:                        refresh(0);
                   5531:                        break;
                   5532:                case 1:
                   5533:                        refresh(0);
                   5534:                        x_putc('\r');
                   5535:                        x_putc('\n');
                   5536:                        x_flush();
                   5537:                        return 1;
                   5538:                }
                   5539:                break;
                   5540: 
                   5541:        case VFAIL:
                   5542:                state = VNORMAL;
                   5543:                x_putc(Ctrl('g'));
                   5544:                break;
                   5545:        }
                   5546:        return 0;
                   5547: }
                   5548: 
                   5549: static int
                   5550: nextstate(ch)
                   5551:        int     ch;
                   5552: {
                   5553:        /*
                   5554:         * probably could have been done more elegantly than
                   5555:         * by creating a new state, but it works
                   5556:         */
                   5557:        if (ch == 'r')
                   5558:                return VREPLACE1CHAR;
                   5559:        else if (isextend(ch))
                   5560:                return VEXTCMD;
                   5561:        else if (issrch(ch))
                   5562:                return VSEARCH;
                   5563:        else if (islong(ch))
                   5564:                return VXCH;
                   5565:        else if (ch == '.')
                   5566:                return VREDO;
                   5567:        else if (iscmd(ch))
                   5568:                return VCMD;
                   5569:        else
                   5570:                return VFAIL;
                   5571: }
                   5572: 
                   5573: static int
                   5574: vi_insert(ch)
                   5575:        int     ch;
                   5576: {
                   5577:        int     tcursor;
                   5578: 
                   5579:        switch (ch) {
                   5580: 
                   5581:        case '\0':
                   5582:                return -1;
                   5583: 
                   5584:        case Ctrl('['):
                   5585:                if (lastcmd[0] == 's' || lastcmd[0] == 'c' ||
                   5586:                                lastcmd[0] == 'C')
                   5587:                        return redo_insert(0);
                   5588:                else
                   5589:                        return redo_insert(lastac - 1);
                   5590: 
                   5591:        case 0x7f:              /* delete */
                   5592:                /* tmp fix */
                   5593:                /* general fix is to get stty erase char and use that
                   5594:                */
                   5595:        case Ctrl('H'):         /* delete */
                   5596:                if (es->cursor != 0) {
                   5597:                        if (inslen > 0)
                   5598:                                inslen--;
                   5599:                        es->cursor--;
                   5600:                        if (insert != REPLACE) {
                   5601:                                memmove(&es->cbuf[es->cursor],
                   5602:                                                &es->cbuf[es->cursor+1],
                   5603:                                                es->linelen - es->cursor);
                   5604:                                es->linelen--;
                   5605:                        }
                   5606:                }
                   5607:                break;
                   5608: 
                   5609:        case Ctrl('U'):
                   5610:                if (es->cursor != 0) {
                   5611:                        inslen = 0;
                   5612:                        memmove(es->cbuf, &es->cbuf[es->cursor],
                   5613:                                                es->linelen - es->cursor);
                   5614:                        es->linelen -= es->cursor;
                   5615:                        es->cursor = 0;
                   5616:                }
                   5617:                break;
                   5618: 
                   5619:        case Ctrl('W'):
                   5620:                if (es->cursor != 0) {
                   5621:                        tcursor = backword(1);
                   5622:                        memmove(&es->cbuf[tcursor], &es->cbuf[es->cursor],
                   5623:                                                es->linelen - es->cursor);
                   5624:                        es->linelen -= es->cursor - tcursor;
                   5625:                        if (inslen < es->cursor - tcursor)
                   5626:                                inslen = 0;
                   5627:                        else
                   5628:                                inslen -= es->cursor - tcursor;
                   5629:                        es->cursor = tcursor;
                   5630:                }
                   5631:                break;
                   5632: 
                   5633:        default:
                   5634:                if (es->linelen == es->cbufsize - 1)
                   5635:                        return -1;
                   5636:                ibuf[inslen++] = ch;
                   5637:                if (insert == INSERT) {
                   5638:                        memmove(&es->cbuf[es->cursor+1], &es->cbuf[es->cursor],
                   5639:                                        es->linelen - es->cursor);
                   5640:                        es->linelen++;
                   5641:                }
                   5642:                es->cbuf[es->cursor++] = ch;
                   5643:                if (insert == REPLACE && es->cursor > es->linelen)
                   5644:                        es->linelen++;
                   5645:        }
                   5646:        return 0;
                   5647: }
                   5648: 
                   5649: static int
                   5650: vi_cmd(argcnt, cmd)
                   5651:        int             argcnt;
                   5652:        char            *cmd;
                   5653: {
                   5654:        int             ncursor;
                   5655:        int             cur, c1, c2, c3 = 0;
                   5656:        struct edstate  *t;
                   5657: 
                   5658: 
                   5659:        if (argcnt == 0) {
                   5660:                if (*cmd == 'G')
                   5661:                        argcnt = hlast + 1;
                   5662:                else if (*cmd != '_')
                   5663:                        argcnt = 1;
                   5664:        }
                   5665: 
                   5666:        if (ismove(*cmd)) {
                   5667:                if ((cur = domove(argcnt, cmd, 0)) >= 0) {
                   5668:                        if (cur == es->linelen && cur != 0)
                   5669:                                cur--;
                   5670:                        es->cursor = cur;
                   5671:                } else
                   5672:                        return -1;
                   5673:        } else {
                   5674:                if (isundoable(*cmd)) {
                   5675:                        undo->winleft = es->winleft;
                   5676:                        memmove(undo->cbuf, es->cbuf, es->linelen);
                   5677:                        undo->linelen = es->linelen;
                   5678:                        undo->cursor = es->cursor;
                   5679:                        lastac = argcnt;
                   5680:                        memmove(lastcmd, cmd, MAXVICMD);
                   5681:                }
                   5682:                switch (*cmd) {
                   5683: 
                   5684:                case Ctrl('r'):
                   5685:                        redraw_line();
                   5686:                        break;
                   5687: 
                   5688:                case 'a':
                   5689:                        modified = 1;
                   5690:                        if (es->linelen != 0)
                   5691:                                es->cursor++;
                   5692:                        insert = INSERT;
                   5693:                        break;
                   5694: 
                   5695:                case 'A':
                   5696:                        modified = 1;
                   5697:                        del_range(0, 0);
                   5698:                        es->cursor = es->linelen;
                   5699:                        insert = INSERT;
                   5700:                        break;
                   5701: 
                   5702:                case 'c':
                   5703:                case 'd':
                   5704:                case 'y':
                   5705:                        if (*cmd == cmd[1]) {
                   5706:                                c1 = 0;
                   5707:                                c2 = es->linelen;
                   5708:                        } else if (!ismove(cmd[1]))
                   5709:                                return -1;
                   5710:                        else {
                   5711:                                if ((ncursor = domove(argcnt, &cmd[1], 1)) < 0)
                   5712:                                        return -1;
                   5713:                                if (*cmd == 'c' &&
                   5714:                                                (cmd[1]=='w' || cmd[1]=='W') &&
                   5715:                                                !isspace(es->cbuf[es->cursor])) {
                   5716:                                        while (isspace(es->cbuf[--ncursor]))
                   5717:                                                ;
                   5718:                                        ncursor++;
                   5719:                                }
                   5720:                                if (ncursor > es->cursor) {
                   5721:                                        c1 = es->cursor;
                   5722:                                        c2 = ncursor;
                   5723:                                } else {
                   5724:                                        c1 = ncursor;
                   5725:                                        c2 = es->cursor;
                   5726:                                }
                   5727:                        }
                   5728:                        if (*cmd != 'c' && c1 != c2)
                   5729:                                yank_range(c1, c2);
                   5730:                        if (*cmd != 'y') {
                   5731:                                del_range(c1, c2);
                   5732:                                es->cursor = c1;
                   5733:                        }
                   5734:                        if (*cmd == 'c') {
                   5735:                                modified = 1;
                   5736:                                insert = INSERT;
                   5737:                        }
                   5738:                        break;
                   5739: 
                   5740:                case 'p':
                   5741:                        modified = 1;
                   5742:                        if (es->linelen != 0)
                   5743:                                es->cursor++;
                   5744:                        while (putbuf(ybuf, yanklen, 0) == 0 && --argcnt > 0)
                   5745:                                ;
                   5746:                        if (es->cursor != 0)
                   5747:                                es->cursor--;
                   5748:                        if (argcnt != 0)
                   5749:                                return -1;
                   5750:                        break;
                   5751: 
                   5752:                case 'P':
                   5753:                        modified = 1;
                   5754:                        while (putbuf(ybuf, yanklen, 0) == 0 && --argcnt > 0)
                   5755:                                ;
                   5756:                        if (es->cursor != 0)
                   5757:                                es->cursor--;
                   5758:                        if (argcnt != 0)
                   5759:                                return -1;
                   5760:                        break;
                   5761: 
                   5762:                case 'C':
                   5763:                        modified = 1;
                   5764:                        del_range(es->cursor, es->linelen);
                   5765:                        insert = INSERT;
                   5766:                        break;
                   5767: 
                   5768:                case 'D':
                   5769:                        yank_range(es->cursor, es->linelen);
                   5770:                        del_range(es->cursor, es->linelen);
                   5771:                        if (es->cursor != 0)
                   5772:                                es->cursor--;
                   5773:                        break;
                   5774: 
                   5775:                case 'G':
                   5776:                        if (grabhist(modified, argcnt - 1) < 0)
                   5777:                                return -1;
                   5778:                        else {
                   5779:                                modified = 0;
                   5780:                                hnum = argcnt - 1;
                   5781:                        }
                   5782:                        break;
                   5783: 
                   5784:                case 'i':
                   5785:                        modified = 1;
                   5786:                        insert = INSERT;
                   5787:                        break;
                   5788: 
                   5789:                case 'I':
                   5790:                        modified = 1;
                   5791:                        es->cursor = 0;
                   5792:                        insert = INSERT;
                   5793:                        break;
                   5794: 
                   5795:                case '+':
                   5796:                case 'j':
                   5797:                        if (grabhist(modified, hnum + argcnt) < 0)
                   5798:                                return -1;
                   5799:                        else {
                   5800:                                modified = 0;
                   5801:                                hnum += argcnt;
                   5802:                        }
                   5803:                        break;
                   5804: 
                   5805:                case '-':
                   5806:                case 'k':
                   5807:                        if (grabhist(modified, hnum - argcnt) < 0)
                   5808:                                return -1;
                   5809:                        else {
                   5810:                                modified = 0;
                   5811:                                hnum -= argcnt;
                   5812:                        }
                   5813:                        break;
                   5814: 
                   5815:                case 'r':
                   5816:                        if (es->linelen == 0)
                   5817:                                return -1;
                   5818:                        modified = 1;
                   5819:                        es->cbuf[es->cursor] = cmd[1];
                   5820:                        break;
                   5821: 
                   5822:                case 'R':
                   5823:                        modified = 1;
                   5824:                        insert = REPLACE;
                   5825:                        break;
                   5826: 
                   5827:                case 's':
                   5828:                        if (es->linelen == 0)
                   5829:                                return -1;
                   5830:                        modified = 1;
                   5831:                        if (es->cursor + argcnt > es->linelen)
                   5832:                                argcnt = es->linelen - es->cursor;
                   5833:                        del_range(es->cursor, es->cursor + argcnt);
                   5834:                        insert = INSERT;
                   5835:                        break;
                   5836: 
                   5837:                case 'x':
                   5838:                        if (es->linelen == 0)
                   5839:                                return -1;
                   5840:                        modified = 1;
                   5841:                        if (es->cursor + argcnt > es->linelen)
                   5842:                                argcnt = es->linelen - es->cursor;
                   5843:                        yank_range(es->cursor, es->cursor + argcnt);
                   5844:                        del_range(es->cursor, es->cursor + argcnt);
                   5845:                        break;
                   5846: 
                   5847:                case 'X':
                   5848:                        if (es->cursor > 0) {
                   5849:                                modified = 1;
                   5850:                                if (es->cursor < argcnt)
                   5851:                                        argcnt = es->cursor;
                   5852:                                yank_range(es->cursor - argcnt, es->cursor);
                   5853:                                del_range(es->cursor - argcnt, es->cursor);
                   5854:                                es->cursor -= argcnt;
                   5855:                        } else
                   5856:                                return -1;
                   5857:                        break;
                   5858: 
                   5859:                case 'u':
                   5860:                        t = es;
                   5861:                        es = undo;
                   5862:                        undo = t;
                   5863:                        break;
                   5864: 
                   5865:                case '?':
                   5866:                        hnum = -1;
                   5867:                        /* ahhhhhh... */
                   5868:                case '/':
                   5869:                        c3 = 1;
                   5870:                        srchlen = 0;
                   5871:                        lastsearch = *cmd;
                   5872:                        /* fall through */
                   5873:                case 'n':
                   5874:                case 'N':
                   5875:                        if (lastsearch == ' ')
                   5876:                                return -1;
                   5877:                        if (lastsearch == '?')
                   5878:                                c1 = 1; 
                   5879:                        else
                   5880:                                c1 = 0;
                   5881:                        if (*cmd == 'N')
                   5882:                                c1 = !c1;
                   5883:                        if ((c2 = grabsearch(modified, hnum,
                   5884:                                                        c1, srchpat)) < 0) {
                   5885:                                if (c3) {
                   5886:                                        restore_cbuf();
                   5887:                                        refresh(0);
                   5888:                                }
                   5889:                                return -1;
                   5890:                        } else {
                   5891:                                modified = 0;
                   5892:                                hnum = c2;
                   5893:                        }
                   5894:                        break;
                   5895:                case '_': {
                   5896:                        int     space;
                   5897:                        char    *p, *sp;
                   5898: 
                   5899:                        (void) histnum(-1);
                   5900:                        p = *histpos();
                   5901: #define issp(c)                (isspace((c)) || (c) == '\n')
                   5902:                        if (argcnt) {
                   5903:                                while (*p && issp(*p))
                   5904:                                        p++;
                   5905:                                while (*p && --argcnt) {
                   5906:                                        while (*p && !issp(*p))
                   5907:                                                p++;
                   5908:                                        while (*p && issp(*p))
                   5909:                                                p++;
                   5910:                                }
                   5911:                                if (!*p)
                   5912:                                        return -1;
                   5913:                                sp = p;
                   5914:                        } else {
                   5915:                                sp = p;
                   5916:                                space = 0;
                   5917:                                while (*p) {
                   5918:                                        if (issp(*p))
                   5919:                                                space = 1;
                   5920:                                        else if (space) {
                   5921:                                                space = 0;
                   5922:                                                sp = p;
                   5923:                                        }
                   5924:                                        p++;
                   5925:                                }
                   5926:                                p = sp;
                   5927:                        }
                   5928:                        modified = 1;
                   5929:                        if (es->linelen != 0)
                   5930:                                es->cursor++;
                   5931:                        while (*p && !issp(*p)) {
                   5932:                                argcnt++;
                   5933:                                p++;
                   5934:                        }
                   5935:                        if (putbuf(" ", 1, 0) != 0)
                   5936:                                argcnt = -1;
                   5937:                        else if (putbuf(sp, argcnt, 0) != 0)
                   5938:                                argcnt = -1;
                   5939:                        if (argcnt < 0) {
                   5940:                                if (es->cursor != 0)
                   5941:                                        es->cursor--;
                   5942:                                return -1;
                   5943:                        }
                   5944:                        insert = INSERT;
                   5945:                        }
                   5946:                        break;
                   5947: 
                   5948:                case '~': {
                   5949:                        char    *p;
                   5950: 
                   5951:                        if (es->linelen == 0)
                   5952:                                return -1;
                   5953:                        p = &es->cbuf[es->cursor];
                   5954:                        if (islower(*p)) {
                   5955:                                modified = 1;
                   5956:                                *p = toupper(*p);
                   5957:                        } else if (isupper(*p)) {
                   5958:                                modified = 1;
                   5959:                                *p = tolower(*p);
                   5960:                        }
                   5961:                        if (es->cursor < es->linelen - 1)
                   5962:                                es->cursor++;
                   5963:                        }
                   5964:                        break;
                   5965: 
                   5966:                case '#':
                   5967:                        es->cursor = 0;
                   5968:                        if (putbuf("#", 1, 0) != 0)
                   5969:                                return -1;
                   5970:                        return 1;
                   5971: 
                   5972:                case '*':
                   5973:                case '=': {
                   5974:                        int     rval = 0;
                   5975:                        int     start, end;
                   5976:                        char    *toglob = undo->cbuf;
                   5977:                        char    **ap;
                   5978:                        char    **ap2;
                   5979:                        char    **globstr();
                   5980: 
                   5981:                        if (isspace(es->cbuf[es->cursor]))
                   5982:                                return -1;
                   5983:                        start = es->cursor;
                   5984:                        while (start > -1 && !isspace(es->cbuf[start]))
                   5985:                                start--;
                   5986:                        start++;
                   5987:                        end = es->cursor;
                   5988:                        while (end < es->linelen && !isspace(es->cbuf[end]))
                   5989:                                end++;
                   5990:                        /* use undo buffer to build word up in */
                   5991:                        memmove(toglob, &es->cbuf[start], end-start);
                   5992:                        if (toglob[end-start-1] != '*') {
                   5993:                                toglob[end-start] = '*';
                   5994:                                toglob[end-start+1] = '\0';
                   5995:                        } else
                   5996:                                toglob[end-start] = '\0';
                   5997:                        ap = globstr(toglob);
                   5998:                        ap2 = ap;
                   5999:                        if (strcmp(ap[0], toglob) == 0 && ap[1] == (char *) 0)
                   6000:                                rval = -1;
                   6001:                        /* restore undo buffer that we used temporarily */
                   6002:                        memmove(toglob, es->cbuf, es->linelen);
                   6003:                        if (rval < 0)
                   6004:                                return rval;
                   6005:                        if (*cmd == '=') {
                   6006:                                fputc('\n', shlout);
                   6007:                                pr_menu(ap2, 0);
                   6008:                                fflush(shlout);
                   6009:                                if (es->linelen != 0)
                   6010:                                        es->cursor++;
                   6011:                                redraw_line();
                   6012:                                insert = INSERT;
                   6013:                                state = VNORMAL;
                   6014:                                return 0;
                   6015:                        } else {
                   6016:                                del_range(start, end);
                   6017:                                es->cursor = start;
                   6018:                                while (1) {
                   6019:                                        if (putbuf(*ap, strlen(*ap), 0) != 0) {
                   6020:                                                rval = -1;
                   6021:                                                break;
                   6022:                                        }
                   6023:                                        if (*++ap == (char *) 0)
                   6024:                                                break;
                   6025:                                        if (putbuf(" ", 1, 0) != 0) {
                   6026:                                                rval = -1;
                   6027:                                                break;
                   6028:                                        }
                   6029: 
                   6030:                                }
                   6031: #if 0
                   6032:                                /*
                   6033:                                 * this is definitely wrong
                   6034:                                 */
                   6035:                                for (ap = ap2; *ap; ap++)
                   6036:                                        free(*ap);
                   6037: 
                   6038:                                free(ap2);
                   6039: #endif
                   6040: 
                   6041:                                modified = 1;
                   6042:                                insert = INSERT;
                   6043:                                refresh(0);
                   6044:                        }
                   6045:                        if (rval != 0)
                   6046:                                return rval;
                   6047:                        }
                   6048:                        break;
                   6049:                }
                   6050:                if (insert == 0 && es->cursor != 0 && es->cursor >= es->linelen)
                   6051:                        es->cursor--;
                   6052:        }
                   6053:        return 0;
                   6054: }
                   6055: 
                   6056: static int
                   6057: domove(argcnt, cmd, sub)
                   6058:        int     argcnt;
                   6059:        char    *cmd;
                   6060:        int     sub;
                   6061: {
                   6062:        int     bcount, i = 0, t;       /* = 0 kludge for gcc -W */
                   6063:        int     ncursor = 0;            /* = 0 kludge for gcc -W */
                   6064: 
                   6065:        switch (*cmd) {
                   6066: 
                   6067:        case 'b':
                   6068:                if (!sub && es->cursor == 0)
                   6069:                        return -1;
                   6070:                ncursor = backword(argcnt);
                   6071:                break;
                   6072: 
                   6073:        case 'B':
                   6074:                if (!sub && es->cursor == 0)
                   6075:                        return -1;
                   6076:                ncursor = Backword(argcnt);
                   6077:                break;
                   6078: 
                   6079:        case 'e':
                   6080:                if (!sub && es->cursor + 1 >= es->linelen)
                   6081:                        return -1;
                   6082:                ncursor = endword(argcnt);
                   6083:                if (sub)
                   6084:                        ncursor++;
                   6085:                break;
                   6086: 
                   6087:        case 'E':
                   6088:                if (!sub && es->cursor + 1 >= es->linelen)
                   6089:                        return -1;
                   6090:                ncursor = Endword(argcnt);
                   6091:                if (sub)
                   6092:                        ncursor++;
                   6093:                break;
                   6094: 
                   6095:        case 'f':
                   6096:        case 'F':
                   6097:        case 't':
                   6098:        case 'T':
                   6099:                fsavecmd = *cmd;
                   6100:                fsavech = cmd[1];
                   6101:                /* drop through */
                   6102: 
                   6103:        case ',':
                   6104:        case ';':
                   6105:                if (fsavecmd == ' ')
                   6106:                        return -1;
                   6107:                i = fsavecmd == 'f' || fsavecmd == 'F';
                   6108:                t = fsavecmd > 'a';
                   6109:                if (*cmd == ',')
                   6110:                        t = !t;
                   6111:                if ((ncursor = findch(fsavech, argcnt, t, i)) < 0)
                   6112:                        return -1;
                   6113:                if (sub && t)
                   6114:                        ncursor++;
                   6115:                break;
                   6116: 
                   6117:        case 'h':
                   6118:                /* tmp fix */
                   6119:        case Ctrl('H'):
                   6120:                if (!sub && es->cursor == 0)
                   6121:                        return -1;
                   6122:                ncursor = es->cursor - argcnt;
                   6123:                if (ncursor < 0)
                   6124:                        ncursor = 0;
                   6125:                break;
                   6126: 
                   6127:        case ' ':
                   6128:        case 'l':
                   6129:                if (!sub && es->cursor + 1 >= es->linelen)
                   6130:                        return -1;
                   6131:                if (es->linelen != 0) {
                   6132:                        ncursor = es->cursor + argcnt;
                   6133:                        if (ncursor >= es->linelen)
                   6134:                                ncursor = es->linelen - 1;
                   6135:                }
                   6136:                break;
                   6137: 
                   6138:        case 'w':
                   6139:                if (!sub && es->cursor + 1 >= es->linelen)
                   6140:                        return -1;
                   6141:                ncursor = forwword(argcnt);
                   6142:                break;
                   6143: 
                   6144:        case 'W':
                   6145:                if (!sub && es->cursor + 1 >= es->linelen)
                   6146:                        return -1;
                   6147:                ncursor = Forwword(argcnt);
                   6148:                break;
                   6149: 
                   6150:        case '0':
                   6151:                ncursor = 0;
                   6152:                break;
                   6153: 
                   6154:        case '^':
                   6155:                ncursor = 0;
                   6156:                while (ncursor < es->linelen - 1 && isspace(es->cbuf[ncursor]))
                   6157:                        ncursor++;
                   6158:                break;
                   6159: 
                   6160:        case '$':
                   6161:                if (es->linelen != 0)
                   6162:                        ncursor = es->linelen;
                   6163:                else
                   6164:                        ncursor = 0;
                   6165:                break;
                   6166: 
                   6167:        case '%':
                   6168:                ncursor = es->cursor;
                   6169:                while (ncursor < es->linelen &&
                   6170:                                (i = bracktype(es->cbuf[ncursor])) == 0)
                   6171:                        ncursor++;
                   6172:                if (ncursor == es->linelen)
                   6173:                        return -1;
                   6174:                bcount = 1;
                   6175:                do {
                   6176:                        if (i > 0) {
                   6177:                                if (++ncursor >= es->linelen)
                   6178:                                        return -1;
                   6179:                        } else {
                   6180:                                if (--ncursor < 0)
                   6181:                                        return -1;
                   6182:                        }
                   6183:                        t = bracktype(es->cbuf[ncursor]);
                   6184:                        if (t == i)
                   6185:                                bcount++;
                   6186:                        else if (t == -i)
                   6187:                                bcount--;
                   6188:                } while (bcount != 0);
                   6189:                if (sub)
                   6190:                        ncursor++;
                   6191:                break;
                   6192: 
                   6193:        default:
                   6194:                return -1;
                   6195:        }
                   6196:        return ncursor;
                   6197: }
                   6198: 
                   6199: static int
                   6200: redo_insert(count)
                   6201:        int     count;
                   6202: {
                   6203:        while (count-- > 0)
                   6204:                if (putbuf(ibuf, inslen, insert==REPLACE) != 0)
                   6205:                        return -1;
                   6206:        if (es->cursor > 0)
                   6207:                es->cursor--;
                   6208:        insert = 0;
                   6209:        return 0;
                   6210: }
                   6211: 
                   6212: static
                   6213: yank_range(a, b)
                   6214:        int     a, b;
                   6215: {
                   6216:        yanklen = b - a;
                   6217:        if (yanklen != 0)
                   6218:                memmove(ybuf, &es->cbuf[a], yanklen);
                   6219: }
                   6220: 
                   6221: static int
                   6222: bracktype(ch)
                   6223:        int     ch;
                   6224: {
                   6225:        switch (ch) {
                   6226: 
                   6227:        case '(':
                   6228:                return 1;
                   6229: 
                   6230:        case '[':
                   6231:                return 2;
                   6232: 
                   6233:        case '{':
                   6234:                return 3;
                   6235: 
                   6236:        case ')':
                   6237:                return -1;
                   6238: 
                   6239:        case ']':
                   6240:                return -2;
                   6241: 
                   6242:        case '}':
                   6243:                return -3;
                   6244: 
                   6245:        default:
                   6246:                return 0;
                   6247:        }
                   6248: }
                   6249: 
                   6250: /*
                   6251:  *     Non user interface editor routines below here
                   6252:  */
                   6253: 
                   6254: static int     cur_col;                /* current column on line */
                   6255: static int     pwidth;                 /* width of prompt */
                   6256: static int     winwidth;               /* width of window */
                   6257: /*static char  *wbuf[2];               /* window buffers */
                   6258: static char    wbuf[2][80-3];  /* window buffers */ /* TODO */
                   6259: static int     win;                    /* window buffer in use */
                   6260: static char    morec;                  /* more character at right of window */
                   6261: static int     lastref;                /* argument to last refresh() */
                   6262: static char    holdbuf[CMDLEN];        /* place to hold last edit buffer */
                   6263: static int     holdlen;                /* length of holdbuf */
                   6264: 
                   6265: save_cbuf()
                   6266: {
                   6267:        memmove(holdbuf, es->cbuf, es->linelen);
                   6268:        holdlen = es->linelen;
                   6269:        holdbuf[holdlen] = '\0';
                   6270: }
                   6271: 
                   6272: restore_cbuf()
                   6273: {
                   6274:        es->cursor = 0;
                   6275:        es->linelen = holdlen;
                   6276:        memmove(es->cbuf, holdbuf, holdlen);
                   6277: }
                   6278: 
                   6279: static
                   6280: edit_reset(buf, len)
                   6281:        char    *buf;
                   6282:        int     len;
                   6283: {
                   6284:        es = &ebuf;
                   6285:        es->cbuf = buf;
                   6286:        es->cbufsize = len;
                   6287:        undo = &undobuf;
                   6288:        undo->cbufsize = len;
                   6289: 
                   6290:        es->linelen = undo->linelen = 0;
                   6291:        es->cursor = undo->cursor = 0;
                   6292:        es->winleft = undo->winleft = 0;
                   6293: 
                   6294:        cur_col = pwidth = promptlen(prompt);
                   6295:        winwidth = x_cols - pwidth - 3;
                   6296:        x_putc('\r');
                   6297:        x_flush();
                   6298:        pprompt(prompt);
                   6299:        /* docap(CLR_EOL, 0); */
                   6300:        win = 0;
                   6301:        morec = ' ';
                   6302:        lastref = 1;
                   6303: }
                   6304: 
                   6305: static int
                   6306: putbuf(buf, len, repl)
                   6307:        char    *buf;
                   6308:        int     len;
                   6309:        int     repl;
                   6310: {
                   6311:        if (len == 0)
                   6312:                return 0;
                   6313:        if (repl) {
                   6314:                if (es->cursor + len >= es->cbufsize - 1)
                   6315:                        return -1;
                   6316:                if (es->cursor + len > es->linelen)
                   6317:                        es->linelen = es->cursor + len;
                   6318:        } else {
                   6319:                if (es->linelen + len >= es->cbufsize - 1)
                   6320:                        return -1;
                   6321:                memmove(&es->cbuf[es->cursor + len], &es->cbuf[es->cursor],
                   6322:                        es->linelen - es->cursor);
                   6323:                es->linelen += len;
                   6324:        }
                   6325:        memmove(&es->cbuf[es->cursor], buf, len);
                   6326:        es->cursor += len;
                   6327:        return 0;
                   6328: }
                   6329: 
                   6330: static
                   6331: stripblanks()
                   6332: {
                   6333:        int     ncursor;
                   6334: 
                   6335:        ncursor = 0;
                   6336:        while (ncursor < es->linelen && isspace(es->cbuf[ncursor]))
                   6337:                ncursor++;
                   6338:        del_range(0, ncursor);
                   6339: }
                   6340: 
                   6341: static
                   6342: del_range(a, b)
                   6343:        int     a, b;
                   6344: {
                   6345:        if (es->linelen != b)
                   6346:                memmove(&es->cbuf[a], &es->cbuf[b], es->linelen - b);
                   6347:        es->linelen -= b - a;
                   6348: }
                   6349: 
                   6350: static int
                   6351: findch(ch, cnt, forw, incl)
                   6352:        int     ch;
                   6353:        int     forw;
                   6354:        int     incl;
                   6355: {
                   6356:        int     ncursor;
                   6357: 
                   6358:        if (es->linelen == 0)
                   6359:                return -1;
                   6360:        ncursor = es->cursor;
                   6361:        while (cnt--) {
                   6362:                do {
                   6363:                        if (forw) {
                   6364:                                if (++ncursor == es->linelen)
                   6365:                                        return -1;
                   6366:                        } else {
                   6367:                                if (--ncursor < 0)
                   6368:                                        return -1;
                   6369:                        }
                   6370:                } while (es->cbuf[ncursor] != ch);
                   6371:        }
                   6372:        if (!incl) {
                   6373:                if (forw)
                   6374:                        ncursor--;
                   6375:                else
                   6376:                        ncursor++;
                   6377:        }
                   6378:        return ncursor;
                   6379: }
                   6380: 
                   6381: #define Isalnum(x) (isalnum(x) || (x == '_'))
                   6382: static int
                   6383: forwword(argcnt)
                   6384:        int     argcnt;
                   6385: {
                   6386:        int     ncursor;
                   6387: 
                   6388:        ncursor = es->cursor;
                   6389:        while (ncursor < es->linelen && argcnt--) {
                   6390:                if (Isalnum(es->cbuf[ncursor]))
                   6391:                        while (Isalnum(es->cbuf[ncursor]) &&
                   6392:                                        ++ncursor < es->linelen)
                   6393:                                ;
                   6394:                else if (!isspace(es->cbuf[ncursor]))
                   6395:                        while (!Isalnum(es->cbuf[ncursor]) &&
                   6396:                                        !isspace(es->cbuf[ncursor]) &&
                   6397:                                        ++ncursor < es->linelen)
                   6398:                                ;
                   6399:                while (isspace(es->cbuf[ncursor]) && ++ncursor < es->linelen)
                   6400:                        ;
                   6401:        }
                   6402:        return ncursor;
                   6403: }
                   6404: 
                   6405: static int
                   6406: backword(argcnt)
                   6407:        int     argcnt;
                   6408: {
                   6409:        int     ncursor;
                   6410: 
                   6411:        ncursor = es->cursor;
                   6412:        while (ncursor > 0 && argcnt--) {
                   6413:                while (--ncursor > 0 && isspace(es->cbuf[ncursor]))
                   6414:                        ;
                   6415:                if (ncursor > 0) {
                   6416:                        if (Isalnum(es->cbuf[ncursor]))
                   6417:                                while (--ncursor >= 0 &&
                   6418:                                   Isalnum(es->cbuf[ncursor]))
                   6419:                                        ;
                   6420:                        else
                   6421:                                while (--ncursor >= 0 &&
                   6422:                                   !Isalnum(es->cbuf[ncursor]) &&
                   6423:                                   !isspace(es->cbuf[ncursor]))
                   6424:                                        ;
                   6425:                        ncursor++;
                   6426:                }
                   6427:        }
                   6428:        return ncursor;
                   6429: }
                   6430: 
                   6431: static int
                   6432: endword(argcnt)
                   6433:        int     argcnt;
                   6434: {
                   6435:        int     ncursor;
                   6436: 
                   6437:        ncursor = es->cursor;
                   6438:        while (ncursor < es->linelen && argcnt--) {
                   6439:                while (++ncursor < es->linelen - 1 &&
                   6440:                                isspace(es->cbuf[ncursor]))
                   6441:                        ;
                   6442:                if (ncursor < es->linelen - 1) {
                   6443:                        if (Isalnum(es->cbuf[ncursor]))
                   6444:                                while (++ncursor < es->linelen &&
                   6445:                                          Isalnum(es->cbuf[ncursor]))
                   6446:                                        ;
                   6447:                        else
                   6448:                                while (++ncursor < es->linelen &&
                   6449:                                   !Isalnum(es->cbuf[ncursor]) &&
                   6450:                                   !isspace(es->cbuf[ncursor]))
                   6451:                                        ;
                   6452:                        ncursor--;
                   6453:                }
                   6454:        }
                   6455:        return ncursor;
                   6456: }
                   6457: 
                   6458: static int
                   6459: Forwword(argcnt)
                   6460:        int     argcnt;
                   6461: {
                   6462:        int     ncursor;
                   6463: 
                   6464:        ncursor = es->cursor;
                   6465:        while (ncursor < es->linelen && argcnt--) {
                   6466:                while (!isspace(es->cbuf[ncursor]) && ++ncursor < es->linelen)
                   6467:                        ;
                   6468:                while (isspace(es->cbuf[ncursor]) && ++ncursor < es->linelen)
                   6469:                        ;
                   6470:        }
                   6471:        return ncursor;
                   6472: }
                   6473: 
                   6474: static int
                   6475: Backword(argcnt)
                   6476:        int     argcnt;
                   6477: {
                   6478:        int     ncursor;
                   6479: 
                   6480:        ncursor = es->cursor;
                   6481:        while (ncursor > 0 && argcnt--) {
                   6482:                while (--ncursor >= 0 && isspace(es->cbuf[ncursor]))
                   6483:                        ;
                   6484:                while (ncursor >= 0 && !isspace(es->cbuf[ncursor]))
                   6485:                        ncursor--;
                   6486:                ncursor++;
                   6487:        }
                   6488:        return ncursor;
                   6489: }
                   6490: 
                   6491: static int
                   6492: Endword(argcnt)
                   6493:        int     argcnt;
                   6494: {
                   6495:        int     ncursor;
                   6496: 
                   6497:        ncursor = es->cursor;
                   6498:        while (ncursor < es->linelen - 1 && argcnt--) {
                   6499:                while (++ncursor < es->linelen - 1 &&
                   6500:                                isspace(es->cbuf[ncursor]))
                   6501:                        ;
                   6502:                if (ncursor < es->linelen - 1) {
                   6503:                        while (++ncursor < es->linelen &&
                   6504:                                        !isspace(es->cbuf[ncursor]))
                   6505:                                ;
                   6506:                        ncursor--;
                   6507:                }
                   6508:        }
                   6509:        return ncursor;
                   6510: }
                   6511: 
                   6512: static int
                   6513: grabhist(save, n)
                   6514:        int     save;
                   6515:        int     n;
                   6516: {
                   6517:        char    *hptr;
                   6518: 
                   6519:        if (n < 0 || n > hlast)
                   6520:                return -1;
                   6521:        if (n == hlast) {
                   6522:                restore_cbuf();
                   6523:                return 0;
                   6524:        }
                   6525:        (void) histnum(n);
                   6526:        if ((hptr = *histpos()) == NULL) {
                   6527:                shellf("grabhist: bad history array\n");
                   6528:                return -1;
                   6529:        }
                   6530:        if (save)
                   6531:                save_cbuf();
                   6532:        es->linelen = strlen(hptr);
                   6533:        memmove(es->cbuf, hptr, es->linelen);
                   6534:        es->cursor = 0;
                   6535:        return 0;
                   6536: }
                   6537: 
                   6538: static int
                   6539: grabsearch(save, start, fwd, pat)
                   6540:        int     save, start, fwd;
                   6541:        char    *pat;
                   6542: {
                   6543:        char    *hptr;
                   6544: 
                   6545:        if ((start == 0 && fwd == 0) || (start >= hlast - 1 && fwd == 1))
                   6546:                return -1;
                   6547:        if ((hptr = findhist(start, fwd, pat)) == NULL) {
                   6548:                /* if (start != 0 && fwd && match(holdbuf, pat) >= 0) { */
                   6549:                if (start != 0 && fwd && strcmp(holdbuf, pat) >= 0) {
                   6550:                        restore_cbuf();
                   6551:                        return 0;
                   6552:                } else
                   6553:                        return -1;
                   6554:        } else if (hptr == (char *)-1) {
                   6555:                return -1;
                   6556:        }
                   6557:        if (save)
                   6558:                save_cbuf();
                   6559:        es->linelen = strlen(hptr);
                   6560:        memmove(es->cbuf, hptr, es->linelen);
                   6561:        es->cursor = 0;
                   6562:        return histN();
                   6563: }
                   6564: 
                   6565: static
                   6566: redraw_line()
                   6567: {
                   6568:        x_putc('\r');
                   6569:        x_putc('\n');
                   6570:        x_flush();
                   6571:        pprompt(prompt);
                   6572:        cur_col = pwidth;
                   6573:        morec = ' ';
                   6574: }
                   6575: 
                   6576: static
                   6577: refresh(leftside)
                   6578:        int             leftside;
                   6579: {
                   6580:        if (leftside < 0)
                   6581:                leftside = lastref;
                   6582:        else
                   6583:                lastref = leftside;
                   6584:        if (outofwin())
                   6585:                rewindow();
                   6586:        display(wbuf[1 - win], wbuf[win], leftside);
                   6587:        win = 1 - win;
                   6588: }
                   6589: 
                   6590: static int
                   6591: outofwin()
                   6592: {
                   6593:        int     cur, col;
                   6594: 
                   6595:        if (es->cursor < es->winleft)
                   6596:                return 1;
                   6597:        col = 0;
                   6598:        cur = es->winleft;
                   6599:        while (cur < es->cursor)
                   6600:                col = newcol(es->cbuf[cur++], col);
                   6601:        if (col > winwidth)
                   6602:                return 1;
                   6603:        return 0;
                   6604: }
                   6605: 
                   6606: static
                   6607: rewindow()
                   6608: {
                   6609:        register int    tcur, tcol;
                   6610:        int             holdcur1, holdcol1;
                   6611:        int             holdcur2, holdcol2;
                   6612: 
                   6613:        holdcur1 = holdcur2 = tcur = 0;
                   6614:        holdcol1 = holdcol2 = tcol = 0;
                   6615:        while (tcur < es->cursor) {
                   6616:                if (tcol - holdcol2 > winwidth / 2) {
                   6617:                        holdcur1 = holdcur2;
                   6618:                        holdcol1 = holdcol2;
                   6619:                        holdcur2 = tcur;
                   6620:                        holdcol2 = tcol;
                   6621:                }
                   6622:                tcol = newcol(es->cbuf[tcur++], tcol);
                   6623:        }
                   6624:        while (tcol - holdcol1 > winwidth / 2)
                   6625:                holdcol1 = newcol(es->cbuf[holdcur1++], holdcol1);
                   6626:        es->winleft = holdcur1;
                   6627: }
                   6628: 
                   6629: static int
                   6630: newcol(ch, col)
                   6631:        int     ch, col;
                   6632: {
                   6633:        if (ch < ' ' || ch == 0x7f) {
                   6634:                if (ch == '\t')
                   6635:                        return (col | 7) + 1;
                   6636:                else
                   6637:                        return col + 2;
                   6638:        } else
                   6639:                return col + 1;
                   6640: }
                   6641: 
                   6642: static
                   6643: display(wb1, wb2, leftside)
                   6644:        char    *wb1, *wb2;
                   6645:        int     leftside;
                   6646: {
                   6647:        char    *twb1, *twb2, mc;
                   6648:        int     cur, col, cnt;
                   6649:        int     ncol = 0; /* set to 0 kludge for gcc -W */
                   6650:        int     moreright;
                   6651: 
                   6652:        col = 0;
                   6653:        cur = es->winleft;
                   6654:        moreright = 0;
                   6655:        twb1 = wb1;
                   6656:        while (col < winwidth && cur < es->linelen) {
                   6657:                if (cur == es->cursor && leftside)
                   6658:                        ncol = col + pwidth;
                   6659:                if (es->cbuf[cur] < ' ' || es->cbuf[cur] == 0x7f) {
                   6660:                        if (es->cbuf[cur] == '\t') {
                   6661:                                do {
                   6662:                                        *twb1++ = ' ';
                   6663:                                } while (++col < winwidth && (col & 7) != 0);
                   6664:                        } else {
                   6665:                                *twb1++ = '^';
                   6666:                                if (++col < winwidth) {
                   6667:                                        *twb1++ = es->cbuf[cur] ^ '@';
                   6668:                                        col++;
                   6669:                                }
                   6670:                        }
                   6671:                } else {
                   6672:                        *twb1++ = es->cbuf[cur];
                   6673:                        col++;
                   6674:                }
                   6675:                if (cur == es->cursor && !leftside)
                   6676:                        ncol = col + pwidth - 1;
                   6677:                cur++;
                   6678:        }
                   6679:        if (cur == es->cursor)
                   6680:                ncol = col + pwidth;
                   6681:        if (col < winwidth) {
                   6682:                while (col < winwidth) {
                   6683:                        *twb1++ = ' ';
                   6684:                        col++;
                   6685:                }
                   6686:        } else
                   6687:                moreright++;
                   6688:        *twb1 = ' ';
                   6689: 
                   6690:        col = pwidth;
                   6691:        cnt = winwidth;
                   6692:        twb1 = wb1;
                   6693:        twb2 = wb2;
                   6694:        while (cnt--) {
                   6695:                if (*twb1 != *twb2) {
                   6696:                        if (cur_col != col)
                   6697:                                ed_mov_opt(col, wb1);
                   6698:                        x_putc(*twb1);
                   6699:                        cur_col++;
                   6700:                }
                   6701:                twb1++;
                   6702:                twb2++;
                   6703:                col++;
                   6704:        }
                   6705:        if (es->winleft > 0 && moreright)
                   6706:                mc = '+';
                   6707:        else if (es->winleft > 0)
                   6708:                mc = '<';
                   6709:        else if (moreright)
                   6710:                mc = '>';
                   6711:        else
                   6712:                mc = ' ';
                   6713:        if (mc != morec) {
                   6714:                ed_mov_opt(x_cols - 2, wb1);
                   6715:                x_putc(mc);
                   6716:                cur_col++;
                   6717:                morec = mc;
                   6718:        }
                   6719: #if 0
                   6720:        /*
                   6721:         * Hack to fix teh ^r redraw problem, but it redraws way too much.
                   6722:         * Probably unacceptable at low baudrates.  Someone please fix this
                   6723:         */
                   6724:        else
                   6725:            {
                   6726:            ed_mov_opt(x_cols - 2, wb1);
                   6727:            }
                   6728: #endif
                   6729:        if (cur_col != ncol)
                   6730:                ed_mov_opt(ncol, wb1);
                   6731: }
                   6732: 
                   6733: static
                   6734: ed_mov_opt(col, wb)
                   6735:        int     col;
                   6736:        char    *wb;
                   6737: {
                   6738:        if (col < cur_col) {
                   6739:                if (col + 1 < cur_col - col) {
                   6740:                        x_putc('\r');
                   6741:                        x_flush();
                   6742:                        pprompt(prompt);
                   6743:                        cur_col = pwidth;
                   6744:                        while (cur_col++ < col)
                   6745:                                x_putc(*wb++);
                   6746:                } else {
                   6747:                        while (cur_col-- > col)
                   6748:                                x_putc('\b');
                   6749:                }
                   6750:        } else {
                   6751:                wb = &wb[cur_col - pwidth];
                   6752:                while (cur_col++ < col)
                   6753:                        x_putc(*wb++);
                   6754:        }
                   6755:        cur_col = col;
                   6756: }
                   6757: 
                   6758: int
                   6759: x_vi(buf, len)
                   6760:        char *buf;
                   6761:        size_t len;
                   6762: {
                   6763:        int     c;
                   6764: 
                   6765:        vi_reset(buf, len > CMDLEN ? CMDLEN : len);
                   6766:        x_flush();
                   6767:        while ((c = getch()) != -1) {
                   6768:                if (vi_hook(c))
                   6769:                        break;
                   6770:                x_flush();
                   6771:        }
                   6772: 
                   6773:        if (c == -1)
                   6774:                return -1;
                   6775: 
                   6776:        if (es->cbuf != buf) {
                   6777:                memmove(buf, es->cbuf, es->linelen);
                   6778:                buf[es->linelen] = '\n';
                   6779:        } else
                   6780:                es->cbuf[es->linelen] = '\n';
                   6781: 
                   6782:        es->linelen++;
                   6783:        return es->linelen;
                   6784: }
                   6785: 
                   6786: getch()
                   6787: {
                   6788:        char    buf;
                   6789: 
                   6790:        if (read(ttyfd, &buf, 1) != 1)
                   6791:                return -1;
                   6792:        if ((buf & 0x7f) == Ctrl('c')) {
                   6793:                /*
                   6794:                 * If you hit ctrl-c, the buffer was left in a
                   6795:                 * strange state; the next command typed was
                   6796:                 * mucked up.  Doing all of this is probably
                   6797:                 * overkill, but it works most of the time.
                   6798:                 */
                   6799:                memset(es->cbuf, 0, CMDLEN);
                   6800:                es->winleft = 0;
                   6801:                es->cbufsize = 0;
                   6802:                es->linelen = 0;
                   6803:                es->cursor = 0;
                   6804: 
                   6805:                memset(undo->cbuf, 0, CMDLEN);
                   6806:                undo->winleft = 0;
                   6807:                undo->cbufsize = 0;
                   6808:                undo->linelen = 0;
                   6809:                undo->cursor = 0;
                   6810:                x_mode(FALSE);
                   6811:                trapsig(SIGINT);
                   6812:        } else if ((buf & 0x7f) == Ctrl('d'))
                   6813:                return -1;
                   6814:        return buf & 0x7f;
                   6815: }
                   6816: 
                   6817: 
                   6818: char **globstr(stuff)
                   6819: char *stuff;
                   6820:     {
                   6821:     char *vecp[2];
                   6822: 
                   6823:     vecp[0] = stuff;
                   6824:     vecp[1] = NULL;
                   6825:     return(eval(vecp, DOBLANK|DOGLOB|DOTILDE));
                   6826:     }
                   6827: #endif /* VI */
                   6828: ./pdksh/sh/c_ksh.c   644    653   1762       26467  5302765310  11306 0ustar  hlu/*
                   6829:  * built-in Korn commands: c_*
                   6830:  */
                   6831: 
                   6832: #ifndef lint
                   6833: static char *RCSid = "$Id: c_ksh.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   6834: #endif
                   6835: 
                   6836: #include "stdh.h"
                   6837: #include <errno.h>
                   6838: #include <setjmp.h>
                   6839: #include <unistd.h>
                   6840: #include "sh.h"
                   6841: 
                   6842: 
                   6843: int
                   6844: c_hash(wp)
                   6845:        register char **wp;
                   6846: {
                   6847:        register struct tbl *tp, **p;
                   6848: 
                   6849:        wp++;
                   6850:        if (*wp == NULL) {
                   6851:                for (p = tsort(&commands); (tp = *p++) != NULL; )
                   6852:                        if ((tp->flag&ISSET))
                   6853:                                printf("%s\n", tp->val.s);
                   6854:                return 0;
                   6855:        }
                   6856: 
                   6857:        if (strcmp(*wp, "-r") == 0)
                   6858:                flushcom(1);
                   6859:        while (*wp != NULL)
                   6860:                findcom(*wp++, 1);
                   6861:        return 0;
                   6862: }
                   6863: 
                   6864: int
                   6865: c_cd(wp)
                   6866:        register char **wp;
                   6867: {
                   6868:        char path [PATH];
                   6869:        char newd [PATH];
                   6870:        register char *cp;
                   6871:        register char *dir;
                   6872:        register char *cdpath;
                   6873:        register char *rep;
                   6874:        register char *pwd = NULL, *oldpwd = NULL;
                   6875:        register int done = 0;
                   6876:        register int prt = 0;
                   6877:        register struct tbl *v_pwd = NULL, *v_oldpwd = NULL;
                   6878: 
                   6879:        if ((dir = wp[1]) == NULL && (dir = strval(global("HOME"))) == NULL)
                   6880:                errorf("no home directory");
                   6881: 
                   6882:        v_pwd = global("PWD");
                   6883:        if ((pwd = strval(v_pwd)) == null) {
                   6884:                setstr(v_pwd, getcwd(path, (size_t)PATH));
                   6885:                pwd = strval(v_pwd);
                   6886:        }
                   6887: 
                   6888:        if (wp[1] != NULL && (rep = wp[2]) != NULL) {
                   6889:                /*
                   6890:                 * Two arg version: cd pat rep
                   6891:                 */
                   6892:                if (strlen(pwd) - strlen(dir) + strlen(rep) >= PATH)
                   6893:                        errorf("substitution too long\n");
                   6894:                cp = strstr(pwd, dir);
                   6895:                if (cp == NULL)
                   6896:                        errorf("substitution failed\n");
                   6897:                strncpy(path, pwd, cp - pwd);           /* first part */
                   6898:                strcpy(path + (cp - pwd), rep);         /* replacement */
                   6899:                strcat(path, cp + strlen(dir));         /* last part */
                   6900:                dir = strsave(path, ATEMP);
                   6901:                prt = 1;
                   6902:        } else if (dir[0] == '-' && dir[1] == '\0') {
                   6903:                /*
                   6904:                 * Change to previous dir: cd -
                   6905:                 */
                   6906:                dir = strval(v_oldpwd = global("OLDPWD"));
                   6907:                prt = 1;
                   6908:        }
                   6909:        if (dir[0] == '/' || (dir[0] == '.' && (dir[1] == '/' ||
                   6910:            (dir[1] == '.' && dir[2] == '/')))) {
                   6911:                /*
                   6912:                 * dir is an explicitly named path, so no CDPATH search
                   6913:                 */
                   6914:                cleanpath(pwd, dir, newd);
                   6915:                if (chdir(newd) < 0)
                   6916:                        errorf("%s: bad directory\n", newd);
                   6917:                else if (prt)
                   6918:                        shellf("%s\n", newd);
                   6919:                flushcom(0);
                   6920:        } else {
                   6921:                /*
                   6922:                 * search CDPATH for dir
                   6923:                 */
                   6924:                cdpath = strval(global("CDPATH"));
                   6925:                while ( !done && cdpath != NULL ) {
                   6926:                        cp = path;
                   6927:                        while (*cdpath && *cdpath != ':')
                   6928:                                *cp++ = *cdpath++;
                   6929:                        if (*cdpath == '\0')
                   6930:                                cdpath = NULL;
                   6931:                        else
                   6932:                                cdpath++;
                   6933:                        if (prt = (cp > path)) {
                   6934:                                *cp++ = '/';
                   6935:                                (void) strcpy( cp, dir );
                   6936:                                cp = path;
                   6937:                        } else
                   6938:                                cp = dir;
                   6939: 
                   6940:                        cleanpath(pwd, cp, newd);
                   6941:                        if (chdir(newd) == 0)
                   6942:                                done = 1;
                   6943:                } while (!done && cdpath != NULL);
                   6944:                if (!done)
                   6945:                        errorf("%s: bad directory\n", dir);
                   6946:                if (prt)
                   6947:                        shellf("%s\n", newd);
                   6948:                flushcom(0);
                   6949:        }
                   6950: 
                   6951:        /*
                   6952:         * Keep track of OLDPWD and PWD
                   6953:         */
                   6954:        oldpwd = pwd;
                   6955:        pwd = newd;
                   6956:        if (!v_oldpwd)
                   6957:                v_oldpwd = global("OLDPWD");
                   6958:        if (oldpwd && *oldpwd)
                   6959:                setstr(v_oldpwd, oldpwd);
                   6960:        else
                   6961:                unset(v_oldpwd);
                   6962:        if (*pwd)
                   6963:                setstr(v_pwd, pwd);
                   6964:        else
                   6965:                unset(v_pwd);
                   6966: 
                   6967:        return 0;
                   6968: }
                   6969: 
                   6970: int
                   6971: c_print(wp)
                   6972:        register char **wp;
                   6973: {
                   6974:        int nl = 1;
                   6975:        int expand = 1;
                   6976:        FILE *f = stdout;
                   6977: 
                   6978:        for (wp++; *wp != NULL && **wp == '-'; wp++) {
                   6979:                register char *s = *wp + 1;
                   6980:                if (*s == '\0') {
                   6981:                        wp++;
                   6982:                        break;
                   6983:                }
                   6984:                while (*s) switch (*s++) {
                   6985:                  case 'n':
                   6986:                        nl = 0;
                   6987:                        break;
                   6988:                  case 'e':
                   6989:                        expand = 1;
                   6990:                        break;
                   6991:                  case 'r':
                   6992:                        expand = 0;
                   6993:                        break;
                   6994:                  case 'u':
                   6995:                        if (!digit(*s) || (f = shf[*s++-'0']) == NULL)
                   6996:                                errorf("bad -u argument\n");
                   6997:                        break;
                   6998:                }
                   6999:        }
                   7000: 
                   7001:        while (*wp != NULL) {
                   7002:                register char *s = *wp;
                   7003:                register int c;
                   7004:                while ((c = *s++) != '\0')
                   7005:                        if (expand && c == '\\') {
                   7006:                                switch ((c = *s++)) {
                   7007:                                case 'b': c = '\b'; break;
                   7008:                                case 'c': nl = 0; continue; /* AT&T brain damage */
                   7009:                                case 'f': c = '\f'; break;
                   7010:                                case 'n': c = '\n'; break;
                   7011:                                case 'r': c = '\r'; break;
                   7012:                                case 't': c = '\t'; break;
                   7013:                                case 'v': c = 0x0B; break;
                   7014:                                case '0': case '1': case '2': case '3':
                   7015:                                case '4': case '5': case '6': case '7':
                   7016:                                        c = c - '0';
                   7017:                                        if (*s >= '0' && *s <= '7')
                   7018:                                                c = 8*c + *s++ - '0';
                   7019:                                        if (*s >= '0' && *s <= '7')
                   7020:                                                c = 8*c + *s++ - '0';
                   7021:                                        break;
                   7022:                                case '\\': break;
                   7023:                                default:
                   7024:                                        putc('\\', f);
                   7025:                                }
                   7026:                                putc(c, f);
                   7027:                        } else
                   7028:                                putc(c, f);
                   7029:                if (*++wp != NULL)
                   7030:                        putc(' ', f);
                   7031:        }
                   7032:        if (nl)
                   7033:                putc('\n', f);
                   7034:        return 0;
                   7035: }
                   7036: 
                   7037: /* todo: handle case where id is both lexical and command */
                   7038: int
                   7039: c_whence(wp)
                   7040:        register char **wp;
                   7041: {
                   7042:        register struct tbl *tp;
                   7043:        char *id;
                   7044:        int vflag = 0;
                   7045:        int ret = 0;
                   7046: 
                   7047:        for (wp++; (id = *wp) != NULL && *id == '-'; wp++)
                   7048:                if (id[1] == 'v')
                   7049:                        vflag = 1;
                   7050: 
                   7051:        while ((id = *wp++) != NULL) {
                   7052:                tp = tsearch(&lexicals, id, hash(id));
                   7053:                if (tp == NULL)
                   7054:                        tp = findcom(id, 0);
                   7055:                if (vflag)
                   7056:                        switch ((tp == NULL) ? CNONE : tp->type) {
                   7057:                          case CNONE:
                   7058:                                printf("%s is unknown\n", id);
                   7059:                                ret = 1;
                   7060:                                break;
                   7061:                          case CSHELL:
                   7062:                                printf("%s is a shell builtin\n", id);
                   7063:                                break;
                   7064:                          case CFUNC:
                   7065:                                printf("%s is a function\n", id);
                   7066:                                fptreef(stdout, "function %s %T\n", id, tp->val.t);
                   7067:                                break;
                   7068:                          case CEXEC:
                   7069:                                printf("%s is %s\n", id,
                   7070:                                       (tp->flag&ISSET) ? tp->val.s : "unknown");
                   7071:                                if (!(tp->flag&ISSET))
                   7072:                                        ret = 1;
                   7073:                                break;
                   7074:                          case CALIAS:
                   7075:                                printf("%s is the alias '%s'\n", id, tp->val.s);
                   7076:                                break;
                   7077:                          case CKEYWD:
                   7078:                                printf("%s is a shell keyword\n", id);
                   7079:                                break;
                   7080:                          default:
                   7081:                                printf("%s is *GOK*\n", id);
                   7082:                                break;
                   7083:                        }
                   7084:                else
                   7085:                        switch ((tp == NULL) ? CNONE : tp->type) {
                   7086:                          case CNONE:
                   7087:                                printf("\n");
                   7088:                                ret = 1;
                   7089:                                break;
                   7090:                          case CSHELL:
                   7091:                                printf("builtin %s\n", id);
                   7092:                                break;
                   7093:                          case CFUNC:
                   7094:                                printf("%s\n", id);
                   7095:                                break;
                   7096:                          case CEXEC:
                   7097:                                printf("%s\n", (tp->flag&ISSET) ? tp->val.s : "");
                   7098:                                if (!(tp->flag&ISSET))
                   7099:                                        ret = 1;
                   7100:                                break;
                   7101:                          case CALIAS:
                   7102:                                printf("%s\n", tp->val.s);
                   7103:                                break;
                   7104:                          case CKEYWD:
                   7105:                                printf("%s\n", id);
                   7106:                                break;
                   7107:                          default:
                   7108:                                printf("*GOK*\n");
                   7109:                                break;
                   7110:                        }
                   7111:        }
                   7112:        return ret;
                   7113: }
                   7114: 
                   7115: /* typeset, export, and readonly */
                   7116: int
                   7117: c_typeset(wp)
                   7118:        register char **wp;
                   7119: {
                   7120:        register char *id;
                   7121:        struct block *l = e.loc;
                   7122:        register struct tbl *vp, **p;
                   7123:        int fset = 0, fclr = 0;
                   7124:        int thing = 0, func = 0, local = 0;
                   7125: 
                   7126:        switch (**wp) {
                   7127:          case 'e':             /* export */
                   7128:                fset |= EXPORT;
                   7129:                break;
                   7130:          case 'r':             /* readonly */
                   7131:                fset |= RDONLY;
                   7132:                break;
                   7133:          case 't':             /* typeset */
                   7134:                local = 1;
                   7135:                break;
                   7136:        }
                   7137: 
                   7138:        for (wp++; (id = *wp) != NULL && (*id == '-' || *id == '+'); wp++) {
                   7139:                int flag = 0;
                   7140:                thing = *id;
                   7141:                while (*++id != '\0') switch (*id) {
                   7142:                  case 'f':
                   7143:                        flag |= FUNCT;
                   7144:                        func = 1;
                   7145:                        break;
                   7146:                  case 'i':
                   7147:                        flag |= INTEGER;
                   7148:                        break;
                   7149:                  case 'r':
                   7150:                        flag |= RDONLY;
                   7151:                        break;
                   7152:                  case 'x':
                   7153:                        flag |= EXPORT;
                   7154:                        break;
                   7155:                  case 't':
                   7156:                        flag |= TRACE;
                   7157:                        break;
                   7158:                  default:
                   7159:                        errorf("unknown flag -%c\n", *id);
                   7160:                }
                   7161:                if (flag != 0) { /* + or - with options */
                   7162:                        if (thing == '-')
                   7163:                                fset |= flag;
                   7164:                        else
                   7165:                                fclr |= flag;
                   7166:                        thing = 0;
                   7167:                }
                   7168:        }
                   7169: 
                   7170:        /* list variables and attributes */
                   7171:        if (*wp == NULL) {
                   7172:                for (l = e.loc; l != NULL; l = l->next) {
                   7173:                    for (p = tsort((func==0) ? &l->vars : &l->funs);
                   7174:                         (vp = *p++) != NULL; )
                   7175:                        if ((vp->flag&ISSET))
                   7176:                            if (thing == 0 && fclr == 0 && fset == 0) {
                   7177:                                printf("typeset ");
                   7178:                                if ((vp->flag&INTEGER))
                   7179:                                        printf("-i ");
                   7180:                                if ((vp->flag&EXPORT))
                   7181:                                        printf("-x ");
                   7182:                                if ((vp->flag&RDONLY))
                   7183:                                        printf("-r ");
                   7184:                                if ((vp->flag&TRACE)) 
                   7185:                                        printf("-t ");
                   7186:                                printf("%s\n", vp->name);
                   7187:                            } else
                   7188:                            if (thing == '+' ||
                   7189:                                (fclr && (vp->flag&fclr) == fclr)) {
                   7190:                                printf("%s\n", vp->name);
                   7191:                            } else
                   7192:                            if (thing == '-' ||
                   7193:                                (fset && (vp->flag&fset) == fset)) {
                   7194:                                if (fset&FUNCT)
                   7195:                                    printf("function %s\n", vp->name);
                   7196:                                else
                   7197:                                    printf("%s=%s\n", vp->name, strval(vp));
                   7198:                            }
                   7199:                }
                   7200:                return (0);
                   7201:        }
                   7202: 
                   7203:        if (local)
                   7204:                fset |= LOCAL;
                   7205:        for (; *wp != NULL; wp++)
                   7206: #if 0
                   7207:                if (func) {
                   7208:                } else
                   7209: #endif
                   7210:                if (typeset(*wp, fset, fclr) == NULL)
                   7211:                        errorf("%s: not identifier\n", *wp);
                   7212:        return 0;
                   7213: }
                   7214:        
                   7215: int
                   7216: c_alias(wp)
                   7217:        register char **wp;
                   7218: {
                   7219:        register struct table *t = &lexicals;
                   7220:        register struct tbl *ap, **p;
                   7221:        int rv = 0;
                   7222: 
                   7223:        if (*++wp != NULL && strcmp(*wp, "-d") == 0) {
                   7224:                t = &homedirs;
                   7225:                wp++;
                   7226:        }
                   7227: 
                   7228:        if (*wp == NULL)
                   7229:                for (p = tsort(t); (ap = *p++) != NULL; )
                   7230:                        if (ap->type == CALIAS && (ap->flag&DEFINED))
                   7231:                                printf("%s='%s'\n", ap->name, ap->val.s);
                   7232: 
                   7233:        for (; *wp != NULL; wp++) {
                   7234:                register char *id = *wp;
                   7235:                register char *val = strchr(id, '=');
                   7236: 
                   7237:                if (val == NULL) {
                   7238:                        ap = tsearch(t, id, hash(id));
                   7239:                        if (ap != NULL && ap->type == CALIAS && (ap->flag&DEFINED))
                   7240:                                printf("%s='%s'\n", ap->name, ap->val.s);
                   7241:                        else
                   7242:                                rv = 1;
                   7243:                } else {
                   7244:                        *val++ = '\0';
                   7245:                        ap = tenter(t, id, hash(id));
                   7246:                        if (ap->type == CKEYWD)
                   7247:                                errorf("cannot alias keyword\n");
                   7248:                        if ((ap->flag&ALLOC)) {
                   7249:                                afree((void*)ap->val.s, APERM);
                   7250:                                ap->flag &= ~(ALLOC|ISSET);
                   7251:                        }
                   7252:                        ap->type = CALIAS;
                   7253:                        ap->val.s = strsave(val, APERM);
                   7254:                        ap->flag |= DEFINED|ALLOC|ISSET;
                   7255:                }
                   7256:        }
                   7257:        return rv;
                   7258: }
                   7259: 
                   7260: int
                   7261: c_unalias(wp)
                   7262:        register char **wp;
                   7263: {
                   7264:        register struct table *t = &lexicals;
                   7265:        register struct tbl *ap;
                   7266: 
                   7267:        if (*++wp != NULL && strcmp(*wp, "-d") == 0) {
                   7268:                t = &homedirs;
                   7269:                wp++;
                   7270:        }
                   7271: 
                   7272:        for (; *wp != NULL; wp++) {
                   7273:                ap = tsearch(t, *wp, hash(*wp));
                   7274:                if (ap == NULL || ap->type != CALIAS)
                   7275:                        continue;
                   7276:                if ((ap->flag&ALLOC))
                   7277:                        afree((void*)ap->val.s, APERM);
                   7278:                ap->flag &= ~(DEFINED|ISSET|ALLOC);
                   7279:        }
                   7280:        return 0;
                   7281: }
                   7282: 
                   7283: int
                   7284: c_let(wp)
                   7285:        char **wp;
                   7286: {
                   7287:        int rv = 1;
                   7288: 
                   7289:        for (wp++; *wp; wp++)
                   7290:                rv = evaluate(*wp) == 0;
                   7291:        return rv;
                   7292: }
                   7293: 
                   7294: int
                   7295: c_jobs(wp)
                   7296:        char **wp;
                   7297: {
                   7298:        j_jobs();
                   7299:        return 0;
                   7300: }
                   7301: 
                   7302: #ifdef JOBS
                   7303: int
                   7304: c_fgbg(wp)
                   7305:        register char **wp;
                   7306: {
                   7307:        int bg = strcmp(*wp, "bg") == 0;
                   7308: 
                   7309:        if (!flag[FMONITOR])
                   7310:                errorf("Job control not enabled\n");
                   7311:        wp++;
                   7312:        j_resume(j_lookup((*wp == NULL) ? "%" : *wp), bg);
                   7313:        return 0;
                   7314: }
                   7315: #endif
                   7316: 
                   7317: int
                   7318: c_kill(wp)
                   7319:        register char **wp;
                   7320: {
                   7321:        register char *cp;
                   7322:        int sig = 15;           /* SIGTERM */
                   7323:        int rv = 0;
                   7324:        int n;
                   7325:        int gotsig = FALSE;
                   7326: 
                   7327:        if (*++wp == NULL)
                   7328:                errorf("Usage: kill [-l] [-signal] {pid|job} ...\n");
                   7329:        if (strcmp(*wp, "-l") == 0) {
                   7330:                register struct trap *p = sigtraps;
                   7331:                for (sig = 0; sig < SIGNALS; sig++, p++)
                   7332:                        if (p->signal)
                   7333:                                printf("%2d %8s %s\n", p->signal, p->name, p->mess);
                   7334:                return 0;
                   7335:        }
                   7336: 
                   7337:        for (; (cp = *wp) != NULL; wp++)
                   7338:                if (*cp == '-' && gotsig == FALSE && *(wp+1) != NULL) {
                   7339:                        struct trap *p;
                   7340:                        gotsig = FALSE;
                   7341:                        if (digit(*(cp+1))) {
                   7342:                                if ((n = atoi(cp+1)) < SIGNALS) {
                   7343:                                        sig = n;
                   7344:                                        gotsig = TRUE;
                   7345:                                } else if (kill(n, sig) < 0) {
                   7346:                                        shellf("%s: %s\n", cp, strerror(errno));
                   7347:                                        rv++;
                   7348:                                }
                   7349:                        } else {
                   7350:                                p = gettrap(cp+1);
                   7351:                                if (p == NULL)
                   7352:                                        errorf("bad signal %s\n", cp+1);
                   7353:                                sig = p->signal;
                   7354:                                gotsig = TRUE;
                   7355:                        }
                   7356:                } else {
                   7357:                        gotsig = FALSE;
                   7358:                        if (digit(*cp) || (*cp == '-' && digit(*(cp+1)))) {
                   7359:                                if (kill(atoi(cp), sig) < 0) {
                   7360:                                        shellf("%s: %s\n", cp, strerror(errno));
                   7361:                                        rv++;
                   7362:                                }
                   7363:                        } else
                   7364:                        if (*cp == '%')
                   7365:                                j_kill(j_lookup(cp), sig);
                   7366:                        else
                   7367:                                errorf("invalid argument\n");
                   7368:                }
                   7369:        return rv;
                   7370: }
                   7371: 
                   7372: #ifdef EMACS
                   7373: int
                   7374: c_bind(wp)
                   7375:        register char **wp;
                   7376: {
                   7377:        int macro = 0;
                   7378:        register char *cp;
                   7379: 
                   7380:        for (wp++; (cp = *wp) != NULL && *cp == '-'; wp++)
                   7381:                if (cp[1] == 'm')
                   7382:                        macro = 1;
                   7383: 
                   7384:        if (*wp == NULL)        /* list all */
                   7385:                x_bind((char*)NULL, (char*)NULL, 0);
                   7386: 
                   7387:        for (; *wp != NULL; wp++) {
                   7388:                cp = strchr(*wp, '=');
                   7389:                if (cp != NULL)
                   7390:                        *cp++ = 0;
                   7391:                x_bind(*wp, cp, macro);
                   7392:        }
                   7393: 
                   7394:        return 0;
                   7395: }
                   7396: #endif
                   7397: 
                   7398: extern c_fc();
                   7399: extern c_getopts();
                   7400: 
                   7401: const struct builtin kshbuiltins [] = {
                   7402:        {"cd", c_cd},
                   7403:        {"print", c_print},
                   7404:        {"getopts", c_getopts},
                   7405:        {"=typeset", c_typeset},
                   7406:        {"=export", c_typeset},
                   7407:        {"=readonly", c_typeset},
                   7408:        {"whence", c_whence},
                   7409:        {"=alias", c_alias},
                   7410:        {"unalias", c_unalias},
                   7411:        {"hash", c_hash},
                   7412:        {"let", c_let},
                   7413:        {"fc", c_fc},
                   7414:        {"jobs", c_jobs},
                   7415:        {"kill", c_kill},
                   7416: #ifdef JOBS
                   7417:        {"fg", c_fgbg},
                   7418:        {"bg", c_fgbg},
                   7419: #endif
                   7420: #ifdef EMACS
                   7421:        {"bind", c_bind},
                   7422: #endif
                   7423:        {NULL, NULL}
                   7424: };
                   7425: 
                   7426: ./pdksh/sh/eval.c   644    653   1762       45522  5302633257  11143 0ustar  hlu/*
                   7427:  * Expansion - quoting, separation, substitution, globbing
                   7428:  */
                   7429: 
                   7430: #ifndef lint
                   7431: static char *RCSid = "$Id: eval.c,v 1.4 1992/08/12 14:15:28 sjg Exp $";
                   7432: #endif
                   7433: 
                   7434: #include "stdh.h"
                   7435: #include <errno.h>
                   7436: #include <setjmp.h>
                   7437: #include <unistd.h>
                   7438: #include <dirent.h>
                   7439: #include <pwd.h>
                   7440: #include "sh.h"
                   7441: #include "expand.h"
                   7442: 
                   7443: /*
                   7444:  * string expansion
                   7445:  *
                   7446:  * first pass: quoting, IFS separation, ${} and $() substitution.
                   7447:  * second pass: filename expansion (*?[]~).
                   7448:  */
                   7449: 
                   7450: /* expansion generator state */
                   7451: typedef struct Expand {
                   7452:        /* int  type; */        /* see expand() */
                   7453:        char   *str;            /* string */
                   7454:        union {
                   7455:                char  **strv;   /* string[] */
                   7456:                FILE   *file;   /* file */
                   7457:        } u;                    /* source */
                   7458:        short   split;          /* split "$@"*/
                   7459: } Expand;
                   7460: 
                   7461: #define        XBASE   0               /* scanning original */
                   7462: #define        XSUB    1               /* expanding ${} string */
                   7463: #define        XARGSEP 2               /* ifs0 between "$@" */
                   7464: #define        XARG    3               /* expanding $*, $@ */
                   7465: #define        XCOM    4               /* expanding $() */
                   7466: 
                   7467: static void     expand      ARGS((char *cp, XPtrV *wp, int f));
                   7468: static int      varsub      ARGS((Expand *xp, char *sp, int stype));
                   7469: static int      comsub      ARGS((Expand *xp, char *cp));
                   7470: static char *   trimsub     ARGS((char *str, char *pat, int how));
                   7471: static void     glob        ARGS((char *cp, XPtrV *wp));
                   7472: static void     globit      ARGS((char *ds, char *dp, char *sp, XPtrV *wp, int check));
                   7473: static char *   debunk      ARGS((char *cp));
                   7474: static char *   tilde       ARGS((char *acp));
                   7475: static char *   homedir     ARGS((char *name));
                   7476: #ifdef ALTERNATIONS
                   7477: static int     alt_expand  ARGS((char *, XPtrV *, int));
                   7478: static int     alt_count   ARGS((char *));
                   7479: static int     alt_scan    ARGS((char **, char **, char,       int));
                   7480: #endif
                   7481: 
                   7482: int    ifs0 = ' ';             /* todo: first char of $IFS */
                   7483: 
                   7484: /* compile and expand word */
                   7485: char *
                   7486: substitute(cp, f)
                   7487:        char const *cp;
                   7488:        int f;
                   7489: {
                   7490:        struct source *s, *sold;
                   7491: 
                   7492:        sold = source;
                   7493:        s = pushs(SWSTR);
                   7494:        s->str = (char *) cp;
                   7495:        source = s;
                   7496:        if (yylex(ONEWORD) != LWORD)
                   7497:                errorf("eval:substitute error\n");
                   7498:        source = sold;
                   7499:        return evalstr(yylval.cp, f);
                   7500: }
                   7501: 
                   7502: /*
                   7503:  * expand arg-list
                   7504:  */
                   7505: char **
                   7506: eval(ap, f)
                   7507:        register char **ap;
                   7508: {
                   7509:        XPtrV w;
                   7510: 
                   7511:        if (*ap == NULL)
                   7512:                return ap;
                   7513:        XPinit(w, 32);
                   7514:        XPput(w, NULL);         /* space for shell name */
                   7515: #ifdef SHARPBANG
                   7516:        XPput(w, NULL);         /* and space for one arg */
                   7517: #endif
                   7518:        while (*ap != NULL)
                   7519:                expand(*ap++, &w, f);
                   7520:        XPput(w, NULL);
                   7521: #ifdef SHARPBANG
                   7522:        return (char **) XPclose(w) + 2;
                   7523: #else
                   7524:        return (char **) XPclose(w) + 1;
                   7525: #endif
                   7526: }
                   7527: 
                   7528: /*
                   7529:  * expand string
                   7530:  */
                   7531: char *
                   7532: evalstr(cp, f)
                   7533:        register char *cp;
                   7534:        int f;
                   7535: {
                   7536:        XPtrV w;
                   7537: 
                   7538:        XPinit(w, 1);
                   7539:        expand(cp, &w, f);
                   7540:        cp = (XPsize(w) == 0) ? "" : (char*) *XPptrv(w);
                   7541:        XPfree(w);
                   7542:        return cp;
                   7543: }
                   7544: 
                   7545: /*
                   7546:  * expand string - return only one component
                   7547:  * used from iosetup to expand redirection files
                   7548:  */
                   7549: char *
                   7550: evalonestr(cp, f)
                   7551:        register char *cp;
                   7552:        int f;
                   7553: {
                   7554:        XPtrV w;
                   7555: 
                   7556:        XPinit(w, 1);
                   7557:        expand(cp, &w, f);
                   7558:        switch (XPsize(w)) {
                   7559:        case 0:
                   7560:                cp = "";
                   7561:                break;
                   7562:        case 1:
                   7563:                cp = (char*) *XPptrv(w);
                   7564:                break;
                   7565:        default:
                   7566:                cp = evalstr(cp, f&~DOGLOB);
                   7567:                break;
                   7568:        }
                   7569:        XPfree(w);
                   7570:        return cp;
                   7571: }
                   7572: 
                   7573: /* for nested substitution: ${var:=$var2} */
                   7574: typedef struct SubType {
                   7575:        short   type;           /* [=+-?%#] action after expanded word */
                   7576:        short   base;           /* begin position of expanded word */
                   7577:        char   *name;           /* name for ${var=word} */
                   7578: } SubType;
                   7579: 
                   7580: static void
                   7581: expand(cp, wp, f)
                   7582:        char *cp;               /* input word */
                   7583:        register XPtrV *wp;     /* output words */
                   7584:        int f;                  /* DO* flags */
                   7585: {
                   7586:        register int c;
                   7587:        register int type = XBASE; /* expansion type */
                   7588:        register int quote = 0; /* quoted */
                   7589:        int quotestack[11];     /* Keep this bigger than the subtype stack */
                   7590:        register int *qst = quotestack + 11;    /* This too, of course */
                   7591:        XString ds;             /* destination string */
                   7592:        register char *dp, *sp; /* dest., source */
                   7593:        int fdo, word, combase; /* second pass flags; have word */
                   7594:        Expand x;               /* expansion variables */
                   7595:        SubType subtype [10];   /* substitution type stack */
                   7596:        register SubType *st = subtype + 10;
                   7597:        int newlines;           /* For trailing newlines in COMSUB */
                   7598:        int trimming = 0;       /* flag if expanding ${var#pat} or ${var%pat} */
                   7599: 
                   7600:        if (cp == NULL)
                   7601:                errorf("eval:expand(NULL)\n");
                   7602:        if (flag[FNOGLOB])
                   7603:                f &= ~ DOGLOB;
                   7604: 
                   7605: #ifdef ALTERNATIONS
                   7606: #define NOALT  BIT(8)          /* internal to this file */
                   7607:                                /* prevent endless recursion */
                   7608:        /* look for '{' in the input word */
                   7609:        if (((f & NOALT) == 0) && (f & DOGLOB) &&
                   7610:            (dp = strchr(cp, '{')) != NULL &&
                   7611:            (dp[-1] == CHAR) &&
                   7612:            !(dp[1] == CHAR && dp[2] == '}')) {
                   7613:                if (alt_expand(cp, wp, f))
                   7614:                        return;
                   7615:        }
                   7616:        f &= ~NOALT;
                   7617: #endif
                   7618: 
                   7619:        Xinit(ds, dp, 128);     /* init dest. string */
                   7620:        type = XBASE;
                   7621:        sp = cp;
                   7622:        fdo = 0;
                   7623:        word = !(f&DOBLANK);
                   7624: 
                   7625:        while (1) {
                   7626:                Xcheck(ds, dp);
                   7627: 
                   7628:                switch (type) {
                   7629:                  case XBASE:   /* original prefixed string */
                   7630:                        c = *sp++;
                   7631:                        switch (c) {
                   7632:                          case EOS:
                   7633:                                c = 0;
                   7634:                                break;
                   7635:                          case CHAR:
                   7636:                                c = *sp++;
                   7637:                                break;
                   7638:                          case QCHAR:
                   7639:                                quote |= 2; /* temporary quote */
                   7640:                                c = *sp++;
                   7641:                                break;
                   7642:                          case OQUOTE:
                   7643:                                word = quote = 1;
                   7644:                                continue;
                   7645:                          case CQUOTE:
                   7646:                                quote = 0;
                   7647:                                continue;
                   7648:                          case COMSUB:
                   7649:                                type = comsub(&x, sp);
                   7650:                                sp = strchr(sp, 0) + 1;
                   7651:                                combase = Xsavepos(ds, dp);
                   7652:                                newlines = 0;
                   7653:                                continue;
                   7654:                          case OSUBST: /* ${var{:}[=+-?]word} */
                   7655:                                cp = sp;                /* variable */
                   7656:                                sp = strchr(sp, 0) + 1; /* skip variable */
                   7657:                                c = (*sp == CSUBST) ? 0 : *sp++;
                   7658:                                if ((c&0x7F) == '#' || (c&0x7F) == '%') {
                   7659:                                        if (flag[FNOUNSET] &&
                   7660:                                            strval(global(cp)) == null)
                   7661:                                                errorf("%s: unset variable\n", cp);
                   7662:                                        trimming++;
                   7663:                                        type = XBASE;
                   7664:                                        *--qst = quote;
                   7665:                                        quote = 0;
                   7666:                                } else
                   7667:                                        type = varsub(&x, cp, c);
                   7668:                                if (type == XBASE) {    /* expand? */
                   7669:                                        if (st == subtype)
                   7670:                                                errorf("ridiculous ${} nesting\n");
                   7671:                                        --st;
                   7672:                                        st->type = c;
                   7673:                                        st->base = Xsavepos(ds, dp);
                   7674:                                        st->name = cp;
                   7675:                                } else
                   7676:                                        sp = wdscan(sp, CSUBST); /* skip word */
                   7677:                                continue;
                   7678:                          case CSUBST: /* only get here if expanding word */
                   7679:                                *dp = 0;
                   7680:                                if (f&DOGLOB)
                   7681:                                        f &= ~DOPAT;
                   7682:                                switch (st->type&0x7F) {
                   7683:                                  case '#':
                   7684:                                  case '%':
                   7685:                                        *dp = 0;
                   7686:                                        dp = Xrestpos(ds, dp, st->base);
                   7687:                                        quote = *qst++;
                   7688:                                        x.str = trimsub(strval(global(st->name)),
                   7689:                                                dp, st->type);
                   7690:                                        type = XSUB;
                   7691:                                        trimming--;
                   7692:                                        continue;
                   7693:                                  case '=':
                   7694: #if 0
                   7695:                                        if ((x.u.vp->flag&RDONLY))
                   7696:                                                errorf("cannot set readonly %s\n", cp);
                   7697: #endif
                   7698:                                        setstr(global(st->name), Xrestpos(ds, dp, st->base));
                   7699:                                        break;
                   7700:                                  case '?':
                   7701:                                        if (dp == Xrestpos(ds, dp, st->base))
                   7702:                                                errorf("missing value for %s\n", cp);
                   7703:                                        else
                   7704:                                                errorf("%s\n", Xrestpos(ds, dp, st->base));
                   7705:                                }
                   7706:                                st++;
                   7707:                                type = XBASE;
                   7708:                                continue;
                   7709:                        }
                   7710:                        break;
                   7711: 
                   7712:                  case XSUB:
                   7713:                        if ((c = *x.str++) == 0) {
                   7714:                                type = XBASE;
                   7715:                                continue;
                   7716:                        }
                   7717:                        break;
                   7718: 
                   7719:                  case XARGSEP:
                   7720:                        type = XARG;
                   7721:                        quote = 1;
                   7722:                  case XARG:
                   7723:                        if ((c = *x.str++) == 0) {
                   7724:                                if ((x.str = *x.u.strv++) == NULL) {
                   7725:                                        type = XBASE;
                   7726:                                        continue;
                   7727:                                } else if (quote && x.split) {
                   7728:                                        /* terminate word for "$@" */
                   7729:                                        type = XARGSEP;
                   7730:                                        quote = 0;
                   7731:                                }
                   7732:                                c = ifs0;
                   7733:                        }
                   7734:                        break;
                   7735: 
                   7736:                  case XCOM:
                   7737:                        if (newlines) {         /* Spit out saved nl's */
                   7738:                                c = '\n';
                   7739:                                --newlines;
                   7740:                        } else {
                   7741:                                while ((c = getc(x.u.file)) == '\n')
                   7742:                                        newlines++;     /* Save newlines */
                   7743:                                if (newlines && c != EOF) {
                   7744:                                        ungetc(c, x.u.file);
                   7745:                                        c = '\n';
                   7746:                                        --newlines;
                   7747:                                }
                   7748:                        }
                   7749:                        if (c == EOF) {
                   7750:                                cp = Xrestpos(ds, sp, combase);
                   7751:                                newlines = 0;
                   7752:                                fclose(x.u.file);
                   7753:                                if (x.split)
                   7754:                                        waitlast();
                   7755:                                type = XBASE;
                   7756:                                continue;
                   7757:                        }
                   7758:                        break;
                   7759:                }
                   7760: 
                   7761:                /* check for end of word or IFS separation */
                   7762:                if (c == 0 || (!quote && (f&DOBLANK) && ctype(c, C_IFS))) {
                   7763:                        if (word) {
                   7764:                                *dp++ = 0;
                   7765:                                cp = Xclose(ds, dp);
                   7766:                                if (fdo&DOTILDE)
                   7767:                                        cp = tilde(cp);
                   7768:                                if (fdo&DOGLOB)
                   7769:                                        glob(cp, wp);
                   7770:                                else
                   7771:                                        {XPput(*wp, cp);}
                   7772:                                fdo = word = 0;
                   7773:                                if (c != 0)
                   7774:                                        Xinit(ds, dp, 128);
                   7775:                        } else
                   7776:                                ; /* ignore IFS */
                   7777:                        if (c == 0)
                   7778:                                return;
                   7779:                } else {
                   7780:                        /* mark any special second pass chars */
                   7781:                        if (!quote)
                   7782:                                switch (c) {
                   7783:                                  case '*':
                   7784:                                  case '?':
                   7785:                                  case '[':
                   7786:                                        if (f&(DOPAT|DOGLOB) || trimming) {
                   7787:                                                fdo |= (f&DOGLOB);
                   7788:                                                *dp++ = MAGIC;
                   7789:                                        }
                   7790:                                        break;
                   7791:                                  case NOT:
                   7792:                                        if ((f&(DOPAT|DOGLOB) || trimming) &&
                   7793:                                            dp[-1] == '[' && dp[-2] == MAGIC) {
                   7794:                                                *dp++ = MAGIC;
                   7795:                                        }
                   7796:                                        break;
                   7797:                                  case '~':
                   7798:                                        if (((f&DOTILDE) &&
                   7799:                                             dp == Xstring(ds, dp)) ||
                   7800:                                            (!(f&DOBLANK) && 
                   7801:                                            (dp[-1] == '=' || dp[-1] == ':'))) {
                   7802:                                                fdo |= DOTILDE;
                   7803:                                                *dp++ = MAGIC;
                   7804:                                        }
                   7805:                                        break;
                   7806:                                }
                   7807:                        else
                   7808:                                quote &= ~2; /* undo temporary */
                   7809: 
                   7810:                        word = 1;
                   7811:                        *dp++ = c; /* save output char */
                   7812:                }
                   7813:        }
                   7814: }
                   7815: 
                   7816: /*
                   7817:  * Prepare to generate the string returned by ${} substitution.
                   7818:  */
                   7819: static int
                   7820: varsub(xp, sp, stype)
                   7821:        register Expand *xp;
                   7822:        register char *sp;
                   7823:        int stype;
                   7824: {
                   7825:        register int c;
                   7826:        int type;
                   7827: 
                   7828:        /* ${#var}, string length or argc */
                   7829:        if (sp[0] == '#' && (c = sp[1]) != 0) {
                   7830:                c = (c == '*' || c == '@') ? e.loc->argc :
                   7831:                        strlen(strval(global(sp+1)));
                   7832:                xp->str = strsave(ulton((unsigned long)c, 10), ATEMP);
                   7833:                return XSUB;
                   7834:        }
                   7835: 
                   7836:        c = sp[0];
                   7837:        if (c == '*' || c == '@') {
                   7838:                if (e.loc->argc == 0) {
                   7839:                        xp->str = null;
                   7840:                        type = XSUB;
                   7841:                } else {
                   7842:                        xp->u.strv = e.loc->argv + 1;
                   7843:                        xp->str = *xp->u.strv++;
                   7844:                        xp->split = c == '@'; /* $@ */
                   7845:                        type = XARG;
                   7846:                }
                   7847:        } else {
                   7848:                if ((xp->str = strval(global(sp))) == NULL)
                   7849:                  xp->str = null;
                   7850:                type = XSUB;
                   7851:        }
                   7852: 
                   7853:        c = stype&0x7F;
                   7854:        /* test the compiler's code generator */
                   7855:        if (c == '%' || c == '#' ||
                   7856:            (((stype&0x80) ? *xp->str=='\0' : xp->str==null) ? /* undef? */
                   7857:             c == '=' || c == '-' || c == '?' : c == '+'))
                   7858:                type = XBASE;   /* expand word instead of variable value */
                   7859:        if (type != XBASE && flag[FNOUNSET] && xp->str == null && c != '+')
                   7860:                errorf("%s: unset variable\n", sp);
                   7861:        return type;
                   7862: }
                   7863: 
                   7864: /*
                   7865:  * Run the command in $(...) and read its output.
                   7866:  */
                   7867: static int
                   7868: comsub(xp, cp)
                   7869:        register Expand *xp;
                   7870:        char *cp;
                   7871: {
                   7872:        Source *s;
                   7873:        register struct op *t;
                   7874:        FILE *fi;
                   7875: 
                   7876:        s = pushs(SSTRING);
                   7877:        s->str = cp;
                   7878:        t = compile(s);
                   7879: 
                   7880:        if (t != NULL && t->type == TCOM && /* $(<file) */
                   7881:            *t->args == NULL && *t->vars == NULL && t->ioact != NULL) {
                   7882:                register struct ioword *io = *t->ioact;
                   7883: 
                   7884:                if ((io->flag&IOTYPE) != IOREAD)
                   7885:                        errorf("funny $() command\n");
                   7886:                fi = fopen(evalstr(io->name, DOTILDE), "r");
                   7887:                if (fi != NULL)
                   7888: #ifdef linux
                   7889:                        setfileno (fi, savefd(fileno(fi)));
                   7890: #else
                   7891:                        fileno(fi) = savefd(fileno(fi));
                   7892: #endif
                   7893:                xp->split = 0;  /* no waitlast() */
                   7894:        } else {
                   7895:                int ofd1, pv[2];
                   7896:                openpipe(pv);
                   7897:                fi = fdopen(pv[0], "r");
                   7898:                ofd1 = savefd(1);
                   7899:                dup2(pv[1], 1);
                   7900:                close(pv[1]);
                   7901: #if 0
                   7902:                exchild(t, XXCOM|XPIPEO);
                   7903: #else
                   7904:                execute(t, XFORK|XXCOM|XPIPEO);
                   7905: #endif
                   7906:                dup2(ofd1, 1);
                   7907:                close(ofd1);
                   7908:                xp->split = 1;  /* waitlast() */
                   7909:        }       
                   7910: 
                   7911:        if (fi == NULL)
                   7912:                errorf("cannot open $() input\n");
                   7913:        setvbuf(fi, (char *)NULL, _IOFBF, BUFSIZ);
                   7914:        xp->u.file = fi;
                   7915:        return XCOM;
                   7916: }
                   7917: 
                   7918: /*
                   7919:  * perform #pattern and %pattern substitution in ${}
                   7920:  */
                   7921: 
                   7922: static char *
                   7923: trimsub(str, pat, how)
                   7924:        register char *str;
                   7925:        char *pat;
                   7926:        int how;
                   7927: {
                   7928:        register char *end = strchr(str, 0);
                   7929:        register char *p, c, *match;
                   7930: 
                   7931:        switch (how&0xff) {     /* UCHAR_MAX maybe? */
                   7932:        case '#':               /* shortest at begin */
                   7933:                for (p = str; p <= end; p++) {
                   7934:                        c = *p; *p = '\0';
                   7935:                        if (gmatch(str, pat)) {
                   7936:                                *p = c;
                   7937:                                return p;
                   7938:                        }
                   7939:                        *p = c;
                   7940:                }
                   7941:                break;
                   7942:        case '#'|0x80:          /* longest match at begin */
                   7943:                for (p = end; p >= str; p--) {
                   7944:                        c = *p; *p = '\0';
                   7945:                        if (gmatch(str, pat)) {
                   7946:                                *p = c;
                   7947:                                return p;
                   7948:                        }
                   7949:                        *p = c;
                   7950:                }
                   7951:                break;
                   7952:        case '%':               /* shortest match at end */
                   7953:                for (p = end; p >= str; p--) {
                   7954:                        if (gmatch(p, pat)) {
                   7955:                                c = *p; *p = '\0';
                   7956:                                match = strsave( str, APERM );  /* APERM? */
                   7957:                                *p = c;
                   7958:                                return match;
                   7959:                        }
                   7960:                }
                   7961:                break;
                   7962:        case '%'|0x80:  /* longest match at end */
                   7963:                for (p = str; p <= end; p++) {
                   7964:                        if (gmatch(p, pat)) {
                   7965:                                c = *p; *p = '\0';
                   7966:                                match = strsave( str, ATEMP );  /* APERM? */
                   7967:                                *p = c;
                   7968:                                return match;
                   7969:                        }
                   7970:                }
                   7971:                break;
                   7972:        }
                   7973: 
                   7974:        return str;             /* no match, return string */
                   7975: }
                   7976: 
                   7977: #ifdef ALTERNATIONS
                   7978: /*     ([email protected])
                   7979:  *     I have decided to `fudge' alternations by picking up
                   7980:  *     the compiled command tree and working with it recursively
                   7981:  *     to generate the set of arguments
                   7982:  *     This has the advantage of making a single discrete change
                   7983:  *     to the code
                   7984:  *
                   7985:  *     This routine calls itself recursively
                   7986:  *     a)      scan forward looking for { building the output string
                   7987:  *             if none found then call expand - and exit
                   7988:  *     b)      When { found, scan forward finding the end }
                   7989:  *     c)      add first alternate to output string
                   7990:  *     d)      scan for the end of the string copying into output
                   7991:  *     e)      call routine with new string
                   7992:  *     Major complication is quoting
                   7993:  */
                   7994: static int
                   7995: alt_expand(cp, wp, f)
                   7996:        char *cp;               /* input word */
                   7997:        register XPtrV *wp;     /* output words */
                   7998:        int f;                  /* DO* flags */
                   7999: {
                   8000:        char *srcp = cp;
                   8001:        char *left;             /* destination string of left hand side */
                   8002:        char *leftend;          /* end of left hand side */
                   8003:        char *alt;              /* start of alterate section */
                   8004:        char *altend;           /* end of alternate section */
                   8005:        char *ap;               /* working pointer */
                   8006:        char *right;            /* right hand side */
                   8007:        char *rp;               /* used to copy right-hand side */
                   8008:        int  maxlen;            /* max string length */
                   8009: 
                   8010:        leftend = left = alloc((maxlen = alt_count(cp)), ATEMP);
                   8011:        
                   8012:        if (alt_scan(&srcp, &leftend, '{', 0) == 0) {
                   8013:                expand(cp, wp, f&NOALT);
                   8014:                afree(left, ATEMP);
                   8015:                return;
                   8016:        }
                   8017: 
                   8018:        /*
                   8019:         *      we have a alternation section
                   8020:         */
                   8021:        alt = altend = alloc(maxlen, ATEMP);
                   8022: 
                   8023:        srcp += 2;
                   8024:        if (alt_scan(&srcp, &altend, '}', 1) == 0) {
                   8025:                afree(left, ATEMP);
                   8026:                afree(alt, ATEMP);
                   8027:                errorf("Missing }.\n");
                   8028:        }
                   8029:        *altend++ = CHAR;
                   8030:        *altend++ = ',';
                   8031:        *altend = EOS;
                   8032:        /*
                   8033:         *      finally we may have a right-hand side
                   8034:         */
                   8035:        right = srcp + 2;
                   8036: 
                   8037:        /*
                   8038:         *      glue the bits together making a new string
                   8039:         */
                   8040:        for (srcp = alt; *srcp != EOS;) {
                   8041: 
                   8042:                ap = leftend;
                   8043: 
                   8044:                if (alt_scan(&srcp, &ap, ',', -1) == 0) {
                   8045:                        afree(left, ATEMP);
                   8046:                        afree(alt, ATEMP);
                   8047:                        errorf("Missing comma.\n");
                   8048:                }
                   8049:                
                   8050:                srcp += 2;
                   8051: 
                   8052:                rp = right;
                   8053:                (void) alt_scan(&rp, &ap, EOS, 0);
                   8054: 
                   8055:                alt_expand(left, wp, f);
                   8056:        }
                   8057:        afree(left, ATEMP);
                   8058:        afree(alt, ATEMP);
                   8059: }
                   8060: 
                   8061: /*
                   8062:  * see how much space we need to hold this tree
                   8063:  */
                   8064: static int
                   8065: alt_count(cp)
                   8066:        register char *cp;
                   8067: {
                   8068:        register int sum = 0;
                   8069:        register char *sp;
                   8070: 
                   8071:        while (*cp != EOS) {
                   8072:                switch(*cp) {
                   8073:                  case CHAR:
                   8074:                  case QCHAR:
                   8075:                        sum += 2;
                   8076:                        cp += 2;
                   8077:                        break;
                   8078:                  case OQUOTE:
                   8079:                  case CQUOTE:
                   8080:                  case CSUBST:
                   8081:                        sum++;
                   8082:                        cp++;
                   8083:                        break;
                   8084:                  case COMSUB:
                   8085:                  case OSUBST:
                   8086:                        sp = cp;
                   8087:                        cp = strchr(sp, 0) + 1;
                   8088:                        sum += cp - sp;
                   8089:                        break;
                   8090:                }
                   8091:        }
                   8092:        return ++sum;
                   8093: }
                   8094: 
                   8095: #ifdef __STDC__
                   8096: static int
                   8097: alt_scan(
                   8098:        char **cpp,             /* address of source pointer */
                   8099:        char **dpp,             /* address of destination pointer */
                   8100:        char endc,              /* last character we are looking for */
                   8101:        int bal)
                   8102: #else
                   8103: static int
                   8104: alt_scan(cpp, dpp, endc, bal)
                   8105:        char **cpp;             /* address of source pointer */
                   8106:        char **dpp;             /* address of destination pointer */
                   8107:        char endc;              /* last character we are looking for */
                   8108:        int bal;
                   8109: #endif
                   8110: {
                   8111:        register char *cp, *dp;
                   8112:        int quote = 0;
                   8113:        int balance = 0;
                   8114:        int usebalance = 0;
                   8115: 
                   8116:        if (bal)
                   8117:        {       usebalance = 1;
                   8118:                balance = (bal < 1) ? 0 : 1;
                   8119:        }
                   8120: 
                   8121:        cp = *cpp;
                   8122:        dp = *dpp;
                   8123: 
                   8124:        while (*cp != EOS) {
                   8125:                switch (*cp) {
                   8126:                  case CHAR:
                   8127:                        if (quote == 1) {
                   8128:                                if (cp[1] == ']')
                   8129:                                        quote = 0;
                   8130:                        }
                   8131:                        else
                   8132:                        if (quote == 0) {
                   8133:                                if (cp[1] == '[')
                   8134:                                        quote = 1;
                   8135:                                else {
                   8136:                                        if (usebalance) {
                   8137:                                                if (cp[1] == '{')
                   8138:                                                        balance++;
                   8139:                                                if (cp[1] == '}')
                   8140:                                                        balance--;
                   8141:                                                }
                   8142:                                        if (cp[1] == endc && balance == 0) {
                   8143:                                                *dp = EOS;
                   8144:                                                *dpp = dp;
                   8145:                                                *cpp = cp;
                   8146:                                                return 1;
                   8147:                                                }
                   8148:                                }
                   8149:                        }
                   8150:                  case QCHAR:
                   8151:                        *dp++ = *cp++;
                   8152:                  copy:
                   8153:                        *dp++ = *cp++;
                   8154:                        break;
                   8155:                        
                   8156:                  case OQUOTE:
                   8157:                        quote = 1;
                   8158:                        goto copy;
                   8159: 
                   8160:                  case CQUOTE:
                   8161:                        quote = 0;
                   8162:                        goto copy;
                   8163: 
                   8164:                  case COMSUB:
                   8165:                  case OSUBST:
                   8166:                        while (*dp++ = *cp++);
                   8167:                        break;
                   8168:                }
                   8169:        }
                   8170:        *dp = EOS;
                   8171:        *cpp = cp;
                   8172:        *dpp = dp;
                   8173:        return 0;
                   8174: }
                   8175: #endif /* ALTERNATIONS */
                   8176: 
                   8177: /*
                   8178:  * glob
                   8179:  * Name derived from V6's /etc/glob, the program that expanded filenames.
                   8180:  */
                   8181: 
                   8182: static char   *debunk();
                   8183: 
                   8184: static void 
                   8185: glob(cp, wp)
                   8186:        char *cp;
                   8187:        register XPtrV *wp;
                   8188: {
                   8189:        char path [PATH];
                   8190:        register char *sp = cp;
                   8191:        int oldsize;
                   8192: 
                   8193:        oldsize = XPsize(*wp);
                   8194:        globit(path, path, sp, wp, 0);
                   8195: 
                   8196:        if (XPsize(*wp) == oldsize)
                   8197:                {XPput(*wp, debunk(cp));}
                   8198:        else
                   8199:                qsortp(XPptrv(*wp) + oldsize, (size_t)(XPsize(*wp) - oldsize), xstrcmp);
                   8200: }
                   8201: 
                   8202: static void
                   8203: globit(ds, dp, sp, wp, check)
                   8204:        char *ds;               /* dest path */
                   8205:        char *dp;               /* dest end */
                   8206:        char *sp;               /* source path */
                   8207:        register XPtrV *wp;     /* output list */
                   8208:        int check;              /* check dest existence */
                   8209: {
                   8210:        register char *np;      /* next source component */
                   8211:        register char *tsp, *tdp;
                   8212: 
                   8213:        if (sp == NULL) {       /* end of source path */
                   8214:                if (check && eaccess(ds, 0) < 0)
                   8215:                        return;
                   8216:                XPput(*wp, strsave(ds, ATEMP));
                   8217:                return;
                   8218:        }
                   8219: 
                   8220:        if (dp > ds)
                   8221:                *dp++ = '/';
                   8222:        while (*sp == '/')
                   8223:                *dp++ = *sp++;
                   8224:        np = strchr(sp, '/');
                   8225:        if (np != NULL)
                   8226:                *np++ = 0;
                   8227: 
                   8228:        *dp = 0;
                   8229:        if (strchr(sp, MAGIC) == NULL) { /* contains no pattern? */
                   8230:                tdp = dp; tsp = sp;
                   8231:                while ((*tdp++ = *tsp++) != 0)
                   8232:                        ;
                   8233:                --tdp;
                   8234:                globit(ds, tdp, np, wp, check);
                   8235:        } else {
                   8236:                DIR *dirp;
                   8237:                struct dirent *d;
                   8238: 
                   8239:                /* ToDo:
                   8240:                 * should not attemp to open() special files: /dev/ttyd0/*
                   8241:                 * opendir should do this check, but Doug Gwyn's does not.
                   8242:                 */
                   8243:                dirp = opendir((*ds == 0) ? "." : ds);
                   8244:                if (dirp == NULL)
                   8245:                        goto Nodir;
                   8246:                while ((d = readdir(dirp)) != NULL) {
                   8247:                        tsp = d->d_name;
                   8248:                        if (tsp[0] == '.' &&
                   8249:                            (tsp[1] == 0 || (tsp[1] == '.' && tsp[2] == 0)))
                   8250:                                continue; /* always ignore . and .. */
                   8251:                        if ((*tsp == '.' && *sp != '.') || !gmatch(tsp, sp))
                   8252:                                continue;
                   8253: 
                   8254:                        tdp = dp;
                   8255:                        while ((*tdp++ = *tsp++) != 0)
                   8256:                                ;
                   8257:                        --tdp;
                   8258:                        globit(ds, tdp, np, wp, np != NULL);
                   8259:                }
                   8260:                closedir(dirp);
                   8261:          Nodir:;
                   8262:        }
                   8263: 
                   8264:        if (np != NULL)
                   8265:                *--np = '/';
                   8266: }
                   8267: 
                   8268: /* remove MAGIC from string */
                   8269: static char *
                   8270: debunk(cp)
                   8271:        char *cp;
                   8272: {
                   8273:        register char *dp, *sp;
                   8274: 
                   8275:        for (dp = sp = cp; *sp != 0; sp++)
                   8276:                if (*sp != MAGIC)
                   8277:                        *dp++ = *sp;
                   8278:        *dp = 0;
                   8279:        return cp;
                   8280: }
                   8281: 
                   8282: /*
                   8283:  * tilde expansion
                   8284:  *
                   8285:  * based on a version by Arnold Robbins
                   8286:  */
                   8287: 
                   8288: static char *homedir();
                   8289: 
                   8290: static char *
                   8291: tilde(acp)
                   8292:        char *acp;
                   8293: {
                   8294:        register int c;
                   8295:        char path [PATH+1];
                   8296:        register char *cp = acp, *wp = path, *dp;
                   8297:        char userid [16+1];
                   8298: 
                   8299:   Again:
                   8300:        while (1) {
                   8301:                if ((c = *cp++) == 0) {
                   8302:                        *wp = 0;
                   8303:                        afree((void*)acp, ATEMP);
                   8304:                        return strsave(path, ATEMP);
                   8305:                } else if (c == MAGIC && *cp == '~')
                   8306:                        break;
                   8307:                else
                   8308:                        *wp++ = c;
                   8309:        }
                   8310: 
                   8311:        dp = NULL;      /* no output substitution */
                   8312:        if (cp[1] == 0 || cp[1] == '/' || cp[1] == ':') /* ~ or ~/ */
                   8313:                dp = strval(global("HOME")), cp += 1;
                   8314:        else if (cp[1] == '+' && (cp[2] == '/' || cp[2] == ':' || cp[2] == 0))
                   8315:                dp = strval(global("PWD")), cp += 2;
                   8316:        else if (cp[1] == '-' && (cp[2] == '/' || cp[2] == ':' || cp[2] == 0))
                   8317:                dp = strval(global("OLDPWD")), cp += 2;
                   8318:        else if (letter(cp[1])) {
                   8319:                char *save = cp;
                   8320:                for (dp = userid, cp++; letnum(*cp) && dp < userid+16; )
                   8321:                        *dp++ = *cp++;
                   8322:                *dp = 0;
                   8323:                dp = homedir(userid);
                   8324:                if (dp == NULL)
                   8325:                        cp = save;
                   8326:        }
                   8327:        /* substitute */
                   8328:        if (dp != NULL)
                   8329:                while (*dp != 0)
                   8330:                        *wp++ = *dp++;
                   8331:        goto Again;
                   8332: }
                   8333: 
                   8334: /*
                   8335:  * map userid to user's home directory.
                   8336:  * todo: implement a cache with the "homedirs" table.
                   8337:  * note that 4.3's getpw adds more than 6K to the shell,
                   8338:  * and the YP version probably adds much more.
                   8339:  * we might consider our own version of getpwnam() to keep the size down.
                   8340:  */
                   8341: 
                   8342: static char *
                   8343: homedir(name)
                   8344:        char *name;
                   8345: {
                   8346:        register struct tbl *ap;
                   8347:        register struct passwd *pw;
                   8348:        extern struct passwd *getpwnam();
                   8349: 
                   8350:        ap = tsearch(&homedirs, name, hash(name));
                   8351:        if ((ap != NULL && (ap->flag&ISSET)))
                   8352:                return ap->val.s;
                   8353:        pw = getpwnam(name);
                   8354:        if (pw == NULL)
                   8355:                return NULL;
                   8356:        return pw->pw_dir;
                   8357: }
                   8358: ./pdksh/sh/lex.c   644    653   1762       30712  5243743661  11004 0ustar  hlu/*
                   8359:  * lexical analysis and source input
                   8360:  */
                   8361: 
                   8362: #ifndef lint
                   8363: static char *RCSid = "$Id: lex.c,v 1.3 1992/08/10 12:02:55 sjg Exp $";
                   8364: #endif
                   8365: 
                   8366: #include "stdh.h"
                   8367: #include <errno.h>
                   8368: #include <setjmp.h>
                   8369: #include <unistd.h>
                   8370: #include <assert.h>
                   8371: #include "sh.h"
                   8372: #include "expand.h"
                   8373: 
                   8374:        int     ttyfd = -1;             /* tty fd for edit and jobs */
                   8375: #ifdef EASY_HISTORY
                   8376:        char   *history[HISTORY];       /* saved commands */
                   8377:        char  **histptr = history - 1;  /* last history item */
                   8378:        int     histpush;               /* number of pushed fc commands */
                   8379: #endif
                   8380: 
                   8381: /* we set s->str to NULLSTR instead of "", so that ungetsc() works */
                   8382: static char    nullstr [] = {0, 0};
                   8383: #define        NULLSTR (nullstr + 1)
                   8384: 
                   8385: static int     expanding_alias;
                   8386: static int     alias;
                   8387: 
                   8388: static void     readhere    ARGS((struct ioword *iop));
                   8389: static int      getsc_      ARGS((void));
                   8390: 
                   8391: /* optimized getsc_() */
                   8392: #define        getsc() ((*source->str != 0) ? *source->str++ : getsc_())
                   8393: #define        ungetsc() (source->str--)
                   8394: 
                   8395: /*
                   8396:  * Lexical analyzer
                   8397:  *
                   8398:  * tokens are not regular expressions, they are LL(1).
                   8399:  * for example, "${var:-${PWD}}", and "$(size $(whence ksh))".
                   8400:  * hence the state stack.
                   8401:  */
                   8402: 
                   8403: int
                   8404: yylex(cf)
                   8405:        int cf;
                   8406: {
                   8407:        register int c, state;
                   8408:        char states [64], *statep = states;
                   8409:        XString ws;             /* expandable output word */
                   8410:        register char *wp;      /* output word pointer */
                   8411:        register char *sp, *dp;
                   8412:        int istate;
                   8413:        int c2;
                   8414:        static int rec_alias_cnt = 0;
                   8415:        static struct tbl *rec_alias_table[20];
                   8416: 
                   8417: 
                   8418:        if (expanding_alias) {
                   8419:                expanding_alias = 0;
                   8420:                while (rec_alias_cnt-- > 0)
                   8421:                        rec_alias_table[rec_alias_cnt]->flag &= ~EXPALIAS;
                   8422:                rec_alias_cnt = 0;
                   8423:        }
                   8424:   Again:
                   8425:        Xinit(ws, wp, 64);
                   8426: 
                   8427:        if (cf&ONEWORD)
                   8428:                istate = SWORD;
                   8429:        else if (cf&LETEXPR)
                   8430:                istate = SDPAREN;
                   8431:        else {                  /* normal lexing */
                   8432:                istate = SBASE;
                   8433:                while ((c = getsc()) == ' ' || c == '\t')
                   8434:                        ;
                   8435:                if (c == '#')
                   8436:                        while ((c = getsc()) != 0 && c != '\n')
                   8437:                                ;
                   8438:                ungetsc();
                   8439:        }
                   8440:        if (alias) {                    /* trailing ' ' in alias definition */
                   8441:                alias = 0;
                   8442:                cf |= ALIAS;
                   8443:        }
                   8444: 
                   8445:        /* collect non-special or quoted characters to form word */
                   8446:        for (*statep = state = istate;
                   8447:             !((c = getsc()) == 0 || (state == SBASE && ctype(c, C_LEX1))); ) {
                   8448:                Xcheck(ws, wp);
                   8449:                switch (state) {
                   8450:                  case SBASE:
                   8451:                  Sbase:
                   8452:                        switch (c) {
                   8453:                          case '\\':
                   8454:                                c = getsc();
                   8455:                                if (c != '\n')
                   8456:                                        *wp++ = QCHAR, *wp++ = c;
                   8457:                                else
                   8458:                                        if (wp == Xstring(ws, wp))
                   8459:                                                goto Again;
                   8460:                                break;
                   8461:                          case '\'':
                   8462:                                *++statep = state = SSQUOTE;
                   8463:                                *wp++ = OQUOTE;
                   8464:                                break;
                   8465:                          case '"':
                   8466:                                *++statep = state = SDQUOTE;
                   8467:                                *wp++ = OQUOTE;
                   8468:                                break;
                   8469:                          default:
                   8470:                                goto Subst;
                   8471:                        }
                   8472:                        break;
                   8473: 
                   8474:                  Subst:
                   8475:                        switch (c) {
                   8476:                          case '\\':
                   8477:                                c = getsc();
                   8478:                                switch (c) {
                   8479:                                  case '\n':
                   8480:                                        break;
                   8481:                                  case '"': case '\\':
                   8482:                                  case '$': case '`':
                   8483:                                        *wp++ = QCHAR, *wp++ = c;
                   8484:                                        break;
                   8485:                                  default:
                   8486:                                        Xcheck(ws, wp);
                   8487:                                        *wp++ = CHAR, *wp++ = '\\';
                   8488:                                        *wp++ = CHAR, *wp++ = c;
                   8489:                                        break;
                   8490:                                }
                   8491:                                break;
                   8492:                          case '$':
                   8493:                                c = getsc();
                   8494:                                if (c == '(') {
                   8495:                                        *++statep = state = SPAREN;
                   8496:                                        *wp++ = COMSUB;
                   8497:                                } else
                   8498:                                if (c == '{') {
                   8499:                                        *++statep = state = SBRACE;
                   8500:                                        *wp++ = OSUBST;
                   8501:                                        c = getsc();
                   8502:                                        do {
                   8503:                                                Xcheck(ws, wp);
                   8504:                                                *wp++ = c;
                   8505:                                                c = getsc();
                   8506:                                        } while (ctype(c, C_ALPHA|C_DIGIT));
                   8507:                                        *wp++ = 0;
                   8508:                                        /* todo: more compile-time checking */
                   8509:                                        if (c == '}')
                   8510:                                                ungetsc();
                   8511:                                        else if (c == '#' || c == '%') {
                   8512:                                                /* Korn pattern trimming */
                   8513:                                                if (getsc() == c)
                   8514:                                                        c |= 0x80;
                   8515:                                                else
                   8516:                                                        ungetsc();
                   8517:                                                *wp++ = c;
                   8518:                                        } else if (c == ':')
                   8519:                                                *wp++ = 0x80|getsc();
                   8520:                                        else
                   8521:                                                *wp++ = c;
                   8522:                                } else if (ctype(c, C_ALPHA)) {
                   8523:                                        *wp++ = OSUBST;
                   8524:                                        do {
                   8525:                                                Xcheck(ws, wp);
                   8526:                                                *wp++ = c;
                   8527:                                                c = getsc();
                   8528:                                        } while (ctype(c, C_ALPHA|C_DIGIT));
                   8529:                                        *wp++ = 0;
                   8530:                                        *wp++ = CSUBST;
                   8531:                                        ungetsc();
                   8532:                                } else if (ctype(c, C_DIGIT|C_VAR1)) {
                   8533:                                        Xcheck(ws, wp);
                   8534:                                        *wp++ = OSUBST;
                   8535:                                        *wp++ = c;
                   8536:                                        *wp++ = 0;
                   8537:                                        *wp++ = CSUBST;
                   8538:                                } else {
                   8539:                                        *wp++ = CHAR, *wp++ = '$';
                   8540:                                        ungetsc();
                   8541:                                }
                   8542:                                break;
                   8543:                          case '`':
                   8544:                                *++statep = state = SBQUOTE;
                   8545:                                *wp++ = COMSUB;
                   8546:                                break;
                   8547:                          default:
                   8548:                                *wp++ = CHAR, *wp++ = c;
                   8549:                        }
                   8550:                        break;
                   8551: 
                   8552:                  case SSQUOTE:
                   8553:                        if (c == '\'') {
                   8554:                                state = *--statep;
                   8555:                                *wp++ = CQUOTE;
                   8556:                        } else
                   8557:                                *wp++ = QCHAR, *wp++ = c;
                   8558:                        break;
                   8559: 
                   8560:                  case SDQUOTE:
                   8561:                        if (c == '"') {
                   8562:                                state = *--statep;
                   8563:                                *wp++ = CQUOTE;
                   8564:                        } else
                   8565:                                goto Subst;
                   8566:                        break;
                   8567: 
                   8568:                  case SPAREN:
                   8569:                        if (c == '(')
                   8570:                                *++statep = state;
                   8571:                        else if (c == ')')
                   8572:                                state = *--statep;
                   8573:                        if (state == SPAREN)
                   8574:                                *wp++ = c;
                   8575:                        else
                   8576:                                *wp++ = 0; /* end of COMSUB */
                   8577:                        break;
                   8578: 
                   8579:                  case SBRACE:
                   8580:                        if (c == '}') {
                   8581:                                state = *--statep;
                   8582:                                *wp++ = CSUBST;
                   8583:                        } else
                   8584:                                goto Sbase;
                   8585:                        break;
                   8586: 
                   8587:                  case SBQUOTE:
                   8588:                        if (c == '`') {
                   8589:                                *wp++ = 0;
                   8590:                                state = *--statep;
                   8591:                        } else if (c == '\\') {
                   8592:                                switch (c = getsc()) {
                   8593:                                  case '\n':
                   8594:                                        break;
                   8595:                                  case '\\':
                   8596:                                  case '$': case '`':
                   8597:                                        *wp++ = c;
                   8598:                                        break;
                   8599:                                  default:
                   8600:                                        *wp++ = '\\';
                   8601:                                        *wp++ = c;
                   8602:                                        break;
                   8603:                                }
                   8604:                        } else
                   8605:                                *wp++ = c;
                   8606:                        break;
                   8607: 
                   8608:                  case SWORD:   /* ONEWORD */
                   8609:                        goto Subst;
                   8610: 
                   8611:                  case SDPAREN: /* LETEXPR */
                   8612:                        if (c == ')') {
                   8613:                                if (getsc() == ')') {
                   8614:                                        c = 0;
                   8615:                                        goto Done;
                   8616:                                } else
                   8617:                                        ungetsc();
                   8618:                        }
                   8619:                        goto Subst;
                   8620:                }
                   8621:        }
                   8622: Done:
                   8623:        Xcheck(ws, wp);
                   8624:        if (state != istate)
                   8625:                yyerror("no closing quote");
                   8626: 
                   8627:        if (c == '<' || c == '>') {
                   8628:                char *cp = Xstring(ws, wp);
                   8629:                if (wp > cp && cp[0] == CHAR && digit(cp[1])) {
                   8630:                        wp = cp; /* throw away word */
                   8631:                        c2/*unit*/ = cp[1] - '0';
                   8632:                } else
                   8633:                        c2/*unit*/ = c == '>'; /* 0 for <, 1 for > */
                   8634:        }
                   8635: 
                   8636:        if (wp == Xstring(ws, wp) && state == SBASE) {
                   8637:                Xfree(ws, sp);  /* free word */
                   8638:                /* no word, process LEX1 character */
                   8639:                switch (c) {
                   8640:                  default:
                   8641:                        return c;
                   8642: 
                   8643:                  case '|':
                   8644:                  case '&':
                   8645:                  case ';':
                   8646:                        if (getsc() == c)
                   8647:                                c = (c == ';') ? BREAK :
                   8648:                                    (c == '|') ? LOGOR :
                   8649:                                    (c == '&') ? LOGAND :
                   8650:                                    YYERRCODE;
                   8651:                        else
                   8652:                                ungetsc();
                   8653:                        return c;
                   8654: 
                   8655:                  case '>':
                   8656:                  case '<': {
                   8657:                        register struct ioword *iop;
                   8658: 
                   8659:                        iop = (struct ioword *) alloc(sizeof(*iop), ATEMP);
                   8660:                        iop->unit = c2/*unit*/;
                   8661: 
                   8662:                        c2 = getsc();
                   8663:                        if (c2 == '>' || c2 == '<') {
                   8664:                                iop->flag = c != c2 ? IORDWR : c == '>' ? IOCAT : IOHERE;
                   8665:                                c2 = getsc();
                   8666:                        } else
                   8667:                                iop->flag = c == '>' ? IOWRITE : IOREAD;
                   8668: 
                   8669:                        if (iop->flag == IOHERE)
                   8670:                                if (c2 == '-')
                   8671:                                        iop->flag |= IOSKIP;
                   8672:                                else
                   8673:                                        ungetsc();
                   8674:                        else
                   8675:                                if (c2 == '&')
                   8676:                                        iop->flag = IODUP;
                   8677:                                else if (c2 == '!' && iop->flag == IOWRITE)
                   8678:                                        iop->flag |= IOCLOB;
                   8679:                                else
                   8680:                                        ungetsc();
                   8681:                        yylval.iop = iop;
                   8682:                        return REDIR;
                   8683:                    }
                   8684:                  case '\n':
                   8685:                        gethere();
                   8686:                        if (cf & CONTIN)
                   8687:                                goto Again;
                   8688:                        return c;
                   8689: 
                   8690:                  case '(':
                   8691:                        c2 = getsc();
                   8692:                        if (c2 == ')')
                   8693:                                c = MPAREN;
                   8694:                        else if (c2 == '(')
                   8695:                                c = MDPAREN;
                   8696:                        else
                   8697:                                ungetsc();
                   8698:                  case ')':
                   8699:                        return c;
                   8700:                }
                   8701:        }
                   8702: 
                   8703:        *wp++ = EOS;            /* terminate word */
                   8704:        yylval.cp = Xclose(ws, wp);
                   8705:        if (state == SWORD || state == SDPAREN) /* ONEWORD? */
                   8706:                return LWORD;
                   8707:        ungetsc();              /* unget terminator */
                   8708: 
                   8709:        /* copy word to unprefixed string ident */
                   8710:        for (sp = yylval.cp, dp = ident; dp < ident+IDENT && (c = *sp++) == CHAR; )
                   8711:                *dp++ = *sp++;
                   8712:        /* Make sure the ident array stays '\0' padded */
                   8713:        while (dp <= ident+IDENT)
                   8714:                *dp++ = '\0';
                   8715: #if 0
                   8716:        if (*ident == '~' || (dp = strchr(ident, '=')) != NULL && dp[1] == '~')
                   8717:                "Tilde expansion";
                   8718: #endif
                   8719:        if (c != EOS)
                   8720:                *ident = 0;     /* word is not unquoted */
                   8721: 
                   8722:        if (*ident != 0 && (cf&(KEYWORD|ALIAS))) {
                   8723:                register struct tbl *p;
                   8724: 
                   8725:                p = tsearch(&lexicals, ident, hash(ident));
                   8726:                if (p != NULL && (p->flag&ISSET))
                   8727:                        if (p->type == CKEYWD && (cf&KEYWORD)) {
                   8728:                                afree(yylval.cp, ATEMP);
                   8729:                                return p->val.i;
                   8730:                        } else if (p->type == CALIAS && (cf&ALIAS) &&
                   8731:                                   !(p->flag&EXPALIAS)) {
                   8732:                                register Source *s;
                   8733: 
                   8734:                                if (rec_alias_cnt == sizeof(rec_alias_table)/sizeof(rec_alias_table[0]))
                   8735:                                        yyerror("excessive recusrsive aliasing");
                   8736:                                else
                   8737:                                        rec_alias_table[rec_alias_cnt++] = p;
                   8738:                                p->flag |= EXPALIAS;
                   8739:                                /* check for recursive aliasing */
                   8740:                                for (s = source; s->type == SALIAS; s = s->next)
                   8741:                                        if (s->u.tblp == p)
                   8742:                                                return LWORD;
                   8743:                                afree(yylval.cp, ATEMP);
                   8744: 
                   8745:                                /* push alias expansion */
                   8746:                                s = pushs(SALIAS);
                   8747:                                s->str = p->val.s;
                   8748:                                s->u.tblp = p;
                   8749:                                s->next = source;
                   8750:                                source = s;
                   8751:                                goto Again;
                   8752:                        } 
                   8753:        }
                   8754: 
                   8755:        return LWORD;
                   8756: }
                   8757: 
                   8758: static void readhere();
                   8759: 
                   8760: gethere()
                   8761: {
                   8762:        register struct ioword **p;
                   8763: 
                   8764:        for (p = heres; p < herep; p++)
                   8765:                readhere(*p);
                   8766:        herep = heres;
                   8767: }
                   8768: 
                   8769: /*
                   8770:  * read "<<word" text into temp file
                   8771:  * todo: set up E_ERR to fclose(f) on unwind
                   8772:  */
                   8773: 
                   8774: static void
                   8775: readhere(iop)
                   8776:        register struct ioword *iop;
                   8777: {
                   8778:        register FILE *f;
                   8779:        struct temp *h;
                   8780:        register int c;
                   8781:        char *eof;
                   8782:        register char *cp;
                   8783:        char line [LINE+1];
                   8784: 
                   8785:        eof = evalstr(iop->name, 0);
                   8786: 
                   8787:        h = maketemp(ATEMP);
                   8788:        h->next = e.temps; e.temps = h;
                   8789:        iop->name = h->name;
                   8790:        f = fopen(h->name, "w");
                   8791:        if (f == NULL)
                   8792:                errorf("Cannot create temporary file\n");
                   8793:        setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
                   8794: 
                   8795:        for (;;) {
                   8796:                cp = line;
                   8797:                while ((c = getsc()) != '\n') {
                   8798:                        if (c == 0)
                   8799:                                errorf("here document `%s' unclosed\n", eof);
                   8800:                        if (cp >= line+LINE)
                   8801:                                break;
                   8802:                        *cp++ = c;
                   8803:                }
                   8804:                ungetsc();
                   8805:                *cp = 0;
                   8806:                for (cp = line; iop->flag&IOSKIP && *cp == '\t'; cp++)
                   8807:                        ;
                   8808:                if (strcmp(eof, cp) == 0 || c == 0)
                   8809:                        break;
                   8810:                while ((c = *cp++) != '\0')
                   8811:                        putc(c, f);
                   8812:                while ((c = getsc()) != '\n') {
                   8813:                        if (c == 0)
                   8814:                                errorf("here document `%s' unclosed\n", eof);
                   8815:                        putc(c, f);
                   8816:                }
                   8817:                putc(c, f);
                   8818:        }
                   8819:        fclose(f);
                   8820: }
                   8821: 
                   8822: void
                   8823: yyerror(msg)
                   8824:        const char *msg;
                   8825: {
                   8826:        yynerrs++;
                   8827:        while (source->type == SALIAS) /* pop aliases */
                   8828:                source = source->next;
                   8829:        if (source->file != NULL)
                   8830:                shellf("%s[%d]: ", source->file, source->line);
                   8831:        source->str = NULLSTR;  /* zap pending input */
                   8832:        errorf("%s\n", msg);
                   8833: }
                   8834: 
                   8835: /*
                   8836:  * input for yylex with alias expansion
                   8837:  */
                   8838: 
                   8839: Source *
                   8840: pushs(type)
                   8841:        int type;
                   8842: {
                   8843:        register Source *s;
                   8844: 
                   8845:        s = (Source *) alloc(sizeof(Source), ATEMP);
                   8846:        s->type = type;
                   8847:        s->str = NULLSTR;
                   8848:        s->line = 0;
                   8849:        s->file = NULL;
                   8850:        s->echo = 0;
                   8851:        s->next = NULL;
                   8852:        return s;
                   8853: }
                   8854: 
                   8855: static int
                   8856: getsc_()
                   8857: {
                   8858:        register Source *s = source;
                   8859:        register int c;
                   8860:        extern void     mprint();
                   8861:        
                   8862:        while ((c = *s->str++) == 0) {
                   8863:                s->str = NULL;          /* return 0 for EOF by default */
                   8864:                switch (s->type) {
                   8865:                  case SEOF:
                   8866:                        s->str = NULLSTR;
                   8867:                        return 0;
                   8868: 
                   8869:                  case STTY:
                   8870:                        if (histpush < 0) {     /* commands pushed by dofc */
                   8871:                                s->type = SHIST;
                   8872:                                s->str = NULLSTR;
                   8873:                                continue;
                   8874:                        }
                   8875:                        s->line++;
                   8876:                        s->str = line;
                   8877:                        line[0] = '\0';
                   8878:                        mprint();
                   8879:                        pprompt(prompt);
                   8880:                        flushshf(1);    flushshf(2);
                   8881:                        /*
                   8882:                         * This allows the arival of a SIGCHLD 
                   8883:                         * to not disturb us until we are ready. 
                   8884:                         * BSD and other systems that 
                   8885:                         * automatically rety a read after an 
                   8886:                         * interrupt don't need this but it 
                   8887:                         * doesn't do any harm either.
                   8888:                         */
                   8889:                      retry:
                   8890: #ifdef EDIT
                   8891: #ifdef EMACS
                   8892:                        if (flag[FEMACS])
                   8893:                                c = x_read(ttyfd, line, LINE);
                   8894:                        else
                   8895: #endif
                   8896: #ifdef VI
                   8897:                        if (flag[FVI])
                   8898:                                c = x_read(ttyfd, line, LINE);
                   8899:                        else
                   8900: #endif
                   8901: #endif
                   8902:                                c = read(ttyfd, line, LINE);
                   8903:                        if (c < 0 && sigchld_caught)
                   8904:                        {
                   8905:                          goto retry;
                   8906:                        }
                   8907:                        if (c < 0)      /* read error */
                   8908:                                c = 0;
                   8909:                        line[c] = '\0';
                   8910:                        prompt = strval(global("PS2"));
                   8911:                        if (c == 0) { /* EOF */
                   8912:                                s->str = NULL;
                   8913:                                s->line--;
                   8914:                        } else {
                   8915:                                c = 0;
                   8916:                                while(line[c] && ctype(line[c], C_IFS))
                   8917:                                        c++;
                   8918:                                if (!line[c]) {
                   8919:                                        s->str = &line[c - 1];
                   8920:                                        s->line--;
                   8921:                                } else {
                   8922:                                        s->str = &line[c];
                   8923: #ifdef EASY_HISTORY
                   8924:                                        histsave(s->str);
                   8925: #else
                   8926:                                        histsave(s->line, s->str, 1);
                   8927: #endif
                   8928:                                }
                   8929:                        }
                   8930:                        break;
                   8931: 
                   8932:                  case SHIST:
                   8933:                        if (histpush == 0) {
                   8934:                                s->type = STTY;
                   8935:                                s->str = NULLSTR;
                   8936:                                continue;
                   8937:                        }
                   8938:                        s->line++;
                   8939:                        s->str = histptr[++histpush];
                   8940: #if 0
                   8941:                        pprompt("!< "); /* todo: PS9 */
                   8942: #endif
                   8943:                        shellf("%s\n", s->str);
                   8944:                        strcpy(line, s->str);
                   8945:                        s->str = strchr(line, 0);
                   8946:                        *s->str++ = '\n';
                   8947:                        *s->str = 0;
                   8948:                        s->str = line;
                   8949:                        break;
                   8950: 
                   8951:                  case SFILE:
                   8952:                        s->line++;
                   8953:                        s->str = fgets(line, LINE, s->u.file);
                   8954:                        if (s->str == NULL)
                   8955:                                if (s->u.file != stdin)
                   8956:                                        fclose(s->u.file);
                   8957:                        break;
                   8958: 
                   8959:                  case SWSTR:
                   8960:                        break;
                   8961: 
                   8962:                  case SSTRING:
                   8963:                        s->str = "\n";
                   8964:                        s->type = SEOF;
                   8965:                        break;
                   8966: 
                   8967:                  case SWORDS:
                   8968:                        s->str = *s->u.strv++;
                   8969:                        s->type = SWORDSEP;
                   8970:                        break;
                   8971: 
                   8972:                  case SWORDSEP:
                   8973:                        if (*s->u.strv == NULL) {
                   8974:                                s->str = "\n";
                   8975:                                s->type = SEOF;
                   8976:                        } else {
                   8977:                                s->str = " ";
                   8978:                                s->type = SWORDS;
                   8979:                        }
                   8980:                        break;
                   8981: 
                   8982:                  case SALIAS:
                   8983:                        s->str = s->u.tblp->val.s;
                   8984:                        if (s->str[0] != 0) {
                   8985:                                c = strchr(s->str, 0)[-1];
                   8986:                                if (c == ' ' || c == '\t')
                   8987:                                        alias = 1;      /* trailing ' ' */
                   8988:                        }
                   8989:                        source = s = s->next;
                   8990:                        expanding_alias = 1;
                   8991:                        continue;
                   8992:                }
                   8993:                if (s->str == NULL) {
                   8994:                        s->type = SEOF;
                   8995:                        s->str = NULLSTR;
                   8996:                        return 0;
                   8997:                }
                   8998:                if (s->echo)
                   8999:                        fputs(s->str, shlout);
                   9000:        }
                   9001:        return c;
                   9002: }
                   9003: 
                   9004: pprompt(cp)
                   9005:        register char *cp;
                   9006: {
                   9007:        while (*cp != 0)
                   9008:                if (*cp != '!')
                   9009:                        putc(*cp++, shlout);
                   9010:                else
                   9011:                        if (*++cp == '!')
                   9012:                                putc(*cp++, shlout);
                   9013:                        else
                   9014:                                shellf("%d", source->line);
                   9015:        fflush(shlout);
                   9016: }
                   9017: ./pdksh/sh/syn.c   644    653   1762       23636  5243743665  11040 0ustar  hlu/*
                   9018:  * shell parser (C version)
                   9019:  */
                   9020: 
                   9021: #ifndef lint
                   9022: static char *RCSid = "$Id: syn.c,v 1.3 1992/08/10 12:03:10 sjg Exp $";
                   9023: #endif
                   9024: 
                   9025: #include "stdh.h"
                   9026: #include <errno.h>
                   9027: #include <setjmp.h>
                   9028: #include "sh.h"
                   9029: #include "expand.h"
                   9030: 
                   9031: static struct op *pipeline  ARGS((int cf));
                   9032: static struct op *andor     ARGS((void));
                   9033: static struct op *c_list    ARGS((void));
                   9034: static struct ioword *synio ARGS((int cf));
                   9035: static void     musthave    ARGS((int c, int cf));
                   9036: static struct op *nested    ARGS((int type, int mark));
                   9037: static struct op *command   ARGS((int cf));
                   9038: static struct op *dogroup   ARGS((int onlydone));
                   9039: static struct op *thenpart  ARGS((void));
                   9040: static struct op *elsepart  ARGS((void));
                   9041: static struct op *caselist  ARGS((void));
                   9042: static struct op *casepart  ARGS((void));
                   9043: static char **  wordlist    ARGS((void));
                   9044: static struct op *block     ARGS((int type, struct op *t1, struct op *t2, char **wp));
                   9045: static struct op *newtp     ARGS((int type));
                   9046: static void     zzerr       ARGS((void));
                   9047: 
                   9048: static struct  op      *outtree; /* yyparse output */
                   9049: 
                   9050: static int     reject;         /* token(cf) gets symbol again */
                   9051: static int     symbol;         /* yylex value */
                   9052: 
                   9053: #define        REJECT  (reject = 1)
                   9054: #define        ACCEPT  (reject = 0)
                   9055: #define        token(cf) \
                   9056:        ((reject) ? (ACCEPT, symbol) : (symbol = yylex(cf)))
                   9057: #define        tpeek(cf) \
                   9058:        ((reject) ? (symbol) : (REJECT, symbol = yylex(cf)))
                   9059: 
                   9060: int
                   9061: yyparse()
                   9062: {
                   9063:        ACCEPT;
                   9064:        yynerrs = 0;
                   9065:        if ((tpeek(KEYWORD|ALIAS)) == 0) { /* EOF */
                   9066:                outtree = newtp(TEOF);
                   9067:                return 0;
                   9068:        }
                   9069:        outtree = c_list();
                   9070:        musthave('\n', 0);
                   9071:        return (yynerrs != 0);
                   9072: }
                   9073: 
                   9074: static struct op *
                   9075: pipeline(cf)
                   9076:        int cf;
                   9077: {
                   9078:        register struct op *t, *p, *tl = NULL;
                   9079:        register int c;
                   9080: 
                   9081:        t = command(cf);
                   9082:        if (t != NULL) {
                   9083:                while ((c = token(0)) == '|') {
                   9084:                        if ((p = command(CONTIN)) == NULL)
                   9085:                                SYNTAXERR;
                   9086:                        if (tl == NULL)
                   9087:                                t = tl = block(TPIPE, t, p, NOWORDS);
                   9088:                        else
                   9089:                                tl = tl->right = block(TPIPE, tl->right, p, NOWORDS);
                   9090:                        /*t = block(TPIPE, t, p, NOWORDS);*/
                   9091:                }
                   9092:                REJECT;
                   9093:        }
                   9094:        return (t);
                   9095: }
                   9096: 
                   9097: static struct op *
                   9098: andor()
                   9099: {
                   9100:        register struct op *t, *p;
                   9101:        register int c;
                   9102: 
                   9103:        t = pipeline(0);
                   9104:        if (t != NULL) {
                   9105:                while ((c = token(0)) == LOGAND || c == LOGOR) {
                   9106:                        if ((p = pipeline(CONTIN)) == NULL)
                   9107:                                SYNTAXERR;
                   9108:                        t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
                   9109:                }
                   9110:                REJECT;
                   9111:        }
                   9112:        return (t);
                   9113: }
                   9114: 
                   9115: static struct op *
                   9116: c_list()
                   9117: {
                   9118:        register struct op *t, *p, *tl = NULL;
                   9119:        register int c;
                   9120: 
                   9121:        t = andor();
                   9122:        if (t != NULL) {
                   9123:                while ((c = token(0)) == ';' || c == '&' ||
                   9124:                       ((multiline || source->type == SSTRING
                   9125:                        || (source->type == SALIAS)) && c == '\n')) {
                   9126:                        if (c == '&') {
                   9127:                                if (tl)
                   9128:                                        tl->right = block(TASYNC, tl->right, NOBLOCK, NOWORDS);
                   9129:                                else
                   9130:                                        t = block(TASYNC, t, NOBLOCK, NOWORDS);
                   9131:                        }
                   9132:                        if ((p = andor()) == NULL)
                   9133:                                return (t);
                   9134:                        if (tl == NULL)
                   9135:                                t = tl = block(TLIST, t, p, NOWORDS);
                   9136:                        else
                   9137:                                tl = tl->right = block(TLIST, tl->right, p, NOWORDS);
                   9138:                }
                   9139:                REJECT;
                   9140:        }
                   9141:        return (t);
                   9142: }
                   9143: 
                   9144: static struct ioword *
                   9145: synio(cf)
                   9146:        int cf;
                   9147: {
                   9148:        register struct ioword *iop;
                   9149: 
                   9150:        if (tpeek(cf) != REDIR)
                   9151:                return NULL;
                   9152:        ACCEPT;
                   9153:        iop = yylval.iop;
                   9154:        musthave(LWORD, 0);
                   9155:        iop->name = yylval.cp;
                   9156:        if ((iop->flag&IOTYPE) == IOHERE) {
                   9157:                if (*ident != 0) /* unquoted */
                   9158:                        iop->flag |= IOEVAL;
                   9159:                if (herep >= &heres[HERES])
                   9160:                        errorf("too many <<'s\n");
                   9161:                *herep++ = iop;
                   9162:        }
                   9163:        return iop;
                   9164: }
                   9165: 
                   9166: static void
                   9167: musthave(c, cf)
                   9168:        int c, cf;
                   9169: {
                   9170:        if ((token(cf)) != c)
                   9171:                SYNTAXERR;
                   9172: }
                   9173: 
                   9174: static struct op *
                   9175: nested(type, mark)
                   9176:        int type, mark;
                   9177: {
                   9178:        register struct op *t;
                   9179: 
                   9180:        multiline++;
                   9181:        t = c_list();
                   9182:        musthave(mark, KEYWORD);
                   9183:        multiline--;
                   9184:        return (block(type, t, NOBLOCK, NOWORDS));
                   9185: }
                   9186: 
                   9187: static struct op *
                   9188: command(cf)
                   9189:        int cf;
                   9190: {
                   9191:        register struct op *t;
                   9192:        register int c, iopn = 0;
                   9193:        struct ioword *iop, **iops;
                   9194:        XPtrV args, vars;
                   9195: 
                   9196:        iops = (struct ioword **) alloc(sizeofN(struct ioword *, NUFILE+1), ATEMP);
                   9197:        XPinit(args, 16);
                   9198:        XPinit(vars, 16);
                   9199: 
                   9200:        if (multiline)
                   9201:                cf = CONTIN;
                   9202:        cf |= KEYWORD|ALIAS;
                   9203: 
                   9204:        while ((iop = synio(cf)) != NULL) {
                   9205:                if (iopn >= NUFILE)
                   9206:                        yyerror("too many redirections");
                   9207:                iops[iopn++] = iop;
                   9208:                cf &=~ CONTIN;
                   9209:        }
                   9210: 
                   9211:        switch (c = token(cf)) {
                   9212:          case 0:
                   9213:                yyerror("unexpected EOF");
                   9214:                return NULL;
                   9215: 
                   9216:          default:
                   9217:                REJECT;
                   9218:                if (iopn == 0)
                   9219:                        return NULL; /* empty line */
                   9220:                t = newtp(TCOM);
                   9221:                break;
                   9222: 
                   9223:          case LWORD:
                   9224:          case MDPAREN:
                   9225:                REJECT;
                   9226:                t = newtp(TCOM);
                   9227:                if (c == MDPAREN) {
                   9228:                        ACCEPT;
                   9229:                        XPput(args,"let");
                   9230:                        musthave(LWORD,LETEXPR);
                   9231:                        XPput(args,yylval.cp);
                   9232:                }
                   9233:                while (1)
                   9234:                        switch (tpeek(0)) {
                   9235:                          case REDIR:
                   9236:                                if (iopn >= NUFILE)
                   9237:                                        yyerror("too many redirections");
                   9238:                                iops[iopn++] = synio(0);
                   9239:                                break;
                   9240: 
                   9241:                          case LWORD:
                   9242:                                ACCEPT;
                   9243:                                if ((XPsize(args) == 0 || flag[FKEYWORD])
                   9244:                                    && strchr(ident+1, '='))
                   9245:                                        {XPput(vars, yylval.cp);}
                   9246:                                else
                   9247:                                        {XPput(args, yylval.cp);}
                   9248:                                break;
                   9249: 
                   9250:                          case MPAREN:
                   9251:                                ACCEPT;
                   9252:                                if (XPsize(args) != 1)
                   9253:                                        SYNTAXERR;
                   9254:                                if (*ident == 0)
                   9255:                                        yyerror("invalid function name\n");
                   9256:                                t = newtp(TFUNCT);
                   9257:                                t->str = strsave(ident, ATEMP);
                   9258:                                musthave('{', CONTIN|KEYWORD);
                   9259:                                t->left = nested(TBRACE, '}');
                   9260:                                return t;
                   9261: 
                   9262:                          default:
                   9263:                                goto Leave;
                   9264:                        }
                   9265:          Leave:
                   9266:                break;
                   9267: 
                   9268:          case '(':
                   9269:                t = nested(TPAREN, ')');
                   9270:                break;
                   9271: 
                   9272:          case '{':
                   9273:                t = nested(TBRACE, '}');
                   9274:                break;
                   9275: 
                   9276:          case FOR:
                   9277:          case SELECT:
                   9278:                t = newtp((c == FOR) ? TFOR: TSELECT);
                   9279:                musthave(LWORD, 0);
                   9280:                t->str = strsave(ident, ATEMP);
                   9281:                multiline++;
                   9282:                t->vars = wordlist();
                   9283:                t->left = dogroup(0);
                   9284:                multiline--;
                   9285:                break;
                   9286: 
                   9287:          case WHILE:
                   9288:          case UNTIL:
                   9289:                multiline++;
                   9290:                t = newtp((c == WHILE) ? TWHILE: TUNTIL);
                   9291:                t->left = c_list();
                   9292:                t->right = dogroup(1);
                   9293:                multiline--;
                   9294:                break;
                   9295: 
                   9296:          case CASE:
                   9297:                t = newtp(TCASE);
                   9298:                musthave(LWORD, 0);
                   9299:                t->str = yylval.cp;
                   9300:                multiline++;
                   9301:                musthave(IN, KEYWORD|CONTIN);
                   9302:                t->left = caselist();
                   9303:                musthave(ESAC, KEYWORD);
                   9304:                multiline--;
                   9305:                break;
                   9306: 
                   9307:          case IF:
                   9308:                multiline++;
                   9309:                t = newtp(TIF);
                   9310:                t->left = c_list();
                   9311:                t->right = thenpart();
                   9312:                musthave(FI, KEYWORD);
                   9313:                multiline--;
                   9314:                break;
                   9315: 
                   9316:          case TIME:
                   9317:                t = pipeline(CONTIN);
                   9318:                t = block(TTIME, t, NOBLOCK, NOWORDS);
                   9319:                break;
                   9320: 
                   9321:          case FUNCTION:
                   9322:                t = newtp(TFUNCT);
                   9323:                musthave(LWORD, 0);
                   9324:                t->str = strsave(ident, ATEMP);
                   9325:                musthave('{', CONTIN|KEYWORD);
                   9326:                t->left = nested(TBRACE, '}');
                   9327:                break;
                   9328: 
                   9329: #if 0
                   9330:          case MDPAREN:
                   9331:                t = newtp(TCOM);
                   9332:                XPput(args, "let");
                   9333:                musthave(LWORD, LETEXPR);
                   9334:                XPput(args, yylval.cp);
                   9335:                while (tpeek(0) == REDIR) {
                   9336:                        if (iopn >= NUFILE)
                   9337:                                yyerror("too many redirections");
                   9338:                        iops[iopn++] = synio(0);
                   9339:                }
                   9340:                break;
                   9341: #endif
                   9342:        }
                   9343: 
                   9344:        while ((iop = synio(0)) != NULL) {
                   9345:                if (iopn >= NUFILE)
                   9346:                        yyerror("too many redirections");
                   9347:                iops[iopn++] = iop;
                   9348:        }
                   9349: 
                   9350:        if (iopn == 0) {
                   9351:                afree((void*) iops, ATEMP);
                   9352:                t->ioact = NULL;
                   9353:        } else {
                   9354:                iops[iopn++] = NULL;
                   9355:                aresize((void*) iops, sizeofN(struct ioword *, iopn), ATEMP);
                   9356:                t->ioact = iops;
                   9357:        }
                   9358: 
                   9359:        if (t->type == TCOM) {
                   9360:                XPput(args, NULL);
                   9361:                t->args = (char **) XPclose(args);
                   9362:                XPput(vars, NULL);
                   9363:                t->vars = (char **) XPclose(vars);
                   9364:        } else {
                   9365:                XPfree(args);
                   9366:                XPfree(vars);
                   9367:        }
                   9368: 
                   9369:        return t;
                   9370: }
                   9371: 
                   9372: static struct op *
                   9373: dogroup(onlydone)
                   9374:        int onlydone;
                   9375: {
                   9376:        register int c;
                   9377:        register struct op *list;
                   9378: 
                   9379:        c = token(CONTIN|KEYWORD);
                   9380:        if (c == DONE && onlydone)
                   9381:                return NULL;
                   9382:        if (c != DO)
                   9383:                SYNTAXERR;
                   9384:        list = c_list();
                   9385:        musthave(DONE, KEYWORD);
                   9386:        return list;
                   9387: }
                   9388: 
                   9389: static struct op *
                   9390: thenpart()
                   9391: {
                   9392:        register int c;
                   9393:        register struct op *t;
                   9394: 
                   9395:        if ((c = token(0)) != THEN) {
                   9396:                REJECT;
                   9397:                return NULL;
                   9398:        }
                   9399:        t = newtp(0);
                   9400:        t->left = c_list();
                   9401:        if (t->left == NULL)
                   9402:                SYNTAXERR;
                   9403:        t->right = elsepart();
                   9404:        return (t);
                   9405: }
                   9406: 
                   9407: static struct op *
                   9408: elsepart()
                   9409: {
                   9410:        register int c;
                   9411:        register struct op *t;
                   9412: 
                   9413:        switch (c = token(0)) {
                   9414:          case ELSE:
                   9415:                if ((t = c_list()) == NULL)
                   9416:                        SYNTAXERR;
                   9417:                return (t);
                   9418: 
                   9419:          case ELIF:
                   9420:                t = newtp(TELIF);
                   9421:                t->left = c_list();
                   9422:                t->right = thenpart();
                   9423:                return (t);
                   9424: 
                   9425:          default:
                   9426:                REJECT;
                   9427:                return NULL;
                   9428:        }
                   9429: }
                   9430: 
                   9431: static struct op *
                   9432: caselist()
                   9433: {
                   9434:        register struct op *t, *tl;
                   9435: 
                   9436:        t = tl = NULL;
                   9437:        while ((tpeek(CONTIN|KEYWORD)) != ESAC) {
                   9438:                struct op *tc = casepart();
                   9439:                if (tl == NULL)
                   9440:                        t = tl = tc, tl->right = NULL;
                   9441:                else
                   9442:                        tl->right = tc, tl = tc;
                   9443:        }
                   9444:        return (t);
                   9445: }
                   9446: 
                   9447: static struct op *
                   9448: casepart()
                   9449: {
                   9450:        register struct op *t;
                   9451:        register int c, cf;
                   9452:        XPtrV ptns;
                   9453: 
                   9454:        XPinit(ptns, 16);
                   9455:        t = newtp(TPAT);
                   9456:        cf = CONTIN|KEYWORD;
                   9457:        c = token(cf);
                   9458:        if (c != '(')
                   9459:                REJECT;
                   9460:        else
                   9461:                cf = 0;
                   9462:        do {
                   9463:                musthave(LWORD, cf);
                   9464:                XPput(ptns, yylval.cp);
                   9465:                cf = 0;
                   9466:        } while ((c = token(0)) == '|');
                   9467:        REJECT;
                   9468:        XPput(ptns, NULL);
                   9469:        t->vars = (char **) XPclose(ptns);
                   9470:        musthave(')', 0);
                   9471: 
                   9472:        t->left = c_list();
                   9473:        if ((tpeek(CONTIN|KEYWORD)) != ESAC)
                   9474:                musthave(BREAK, CONTIN|KEYWORD);
                   9475:        return (t);
                   9476: }
                   9477: 
                   9478: static char **
                   9479: wordlist()
                   9480: {
                   9481:        register int c;
                   9482:        XPtrV args;
                   9483: 
                   9484:        XPinit(args, 16);
                   9485:        if ((c = token(CONTIN|KEYWORD)) != IN) {
                   9486:                REJECT;
                   9487:                return NULL;
                   9488:        }
                   9489:        while ((c = token(0)) == LWORD)
                   9490:                XPput(args, yylval.cp);
                   9491:        if (c != '\n' && c != ';')
                   9492:                SYNTAXERR;
                   9493:        if (XPsize(args) == 0) {
                   9494:                XPfree(args);
                   9495:                return NULL;
                   9496:        } else {
                   9497:                XPput(args, NULL);
                   9498:                return (char **) XPclose(args);
                   9499:        }
                   9500: }
                   9501: 
                   9502: /*
                   9503:  * supporting functions
                   9504:  */
                   9505: 
                   9506: static struct op *
                   9507: block(type, t1, t2, wp)
                   9508:        struct op *t1, *t2;
                   9509:        char **wp;
                   9510: {
                   9511:        register struct op *t;
                   9512: 
                   9513:        t = newtp(type);
                   9514:        t->left = t1;
                   9515:        t->right = t2;
                   9516:        t->vars = wp;
                   9517:        return (t);
                   9518: }
                   9519: 
                   9520: const  struct res {
                   9521:        char    *name;
                   9522:        int     val;
                   9523: } restab[] = {
                   9524:        "for",          FOR,
                   9525:        "select",       SELECT,
                   9526:        "case",         CASE,
                   9527:        "esac",         ESAC,
                   9528:        "while",        WHILE,
                   9529:        "do",           DO,
                   9530:        "done",         DONE,
                   9531:        "if",           IF,
                   9532:        "in",           IN,
                   9533:        "then",         THEN,
                   9534:        "else",         ELSE,
                   9535:        "elif",         ELIF,
                   9536:        "until",        UNTIL,
                   9537:        "fi",           FI,
                   9538:        "function",     FUNCTION,
                   9539:        "time",         TIME,
                   9540:        "{",            '{',
                   9541:        "}",            '}',
                   9542:        0
                   9543: };
                   9544: 
                   9545: keywords()
                   9546: {
                   9547:        register struct res const *rp;
                   9548:        register struct tbl *p;
                   9549: 
                   9550:        for (rp = restab; rp->name; rp++) {
                   9551:                p = tenter(&lexicals, rp->name, hash(rp->name));
                   9552:                p->flag |= DEFINED|ISSET;
                   9553:                p->type = CKEYWD;
                   9554:                p->val.i = rp->val;
                   9555:        }
                   9556: }
                   9557: 
                   9558: static struct op *
                   9559: newtp(type)
                   9560:        int type;
                   9561: {
                   9562:        register struct op *t;
                   9563: 
                   9564:        t = (struct op *) alloc(sizeof(*t), ATEMP);
                   9565:        t->type = type;
                   9566:        t->args = t->vars = NULL;
                   9567:        t->ioact = NULL;
                   9568:        t->left = t->right = NULL;
                   9569:        t->str = NULL;
                   9570:        return (t);
                   9571: }
                   9572: 
                   9573: static void
                   9574: zzerr()
                   9575: {
                   9576:        yyerror("syntax error");
                   9577: }
                   9578: 
                   9579: struct op *
                   9580: compile(s)
                   9581:        Source *s;
                   9582: {
                   9583:        yynerrs = 0;
                   9584:        multiline = 0;
                   9585:        herep = heres;
                   9586:        source = s;
                   9587:        if (yyparse())
                   9588:                unwind();
                   9589:        if (s->type == STTY || s->type == SFILE || s->type == SHIST)
                   9590:                s->str = null;  /* line is not preserved */
                   9591:        return outtree;
                   9592: }
                   9593: 
                   9594: ./pdksh/sh/c_sh.c   644    653   1762       21073  5302766212  11121 0ustar  hlu/*
                   9595:  * built-in Bourne commands
                   9596:  */
                   9597: 
                   9598: #ifndef lint
                   9599: static char *RCSid = "$Id: c_sh.c,v 1.3 1992/04/25 08:29:52 sjg Exp $";
                   9600: #endif
                   9601: 
                   9602: #include "stdh.h"
                   9603: #include <errno.h>
                   9604: #include <signal.h>
                   9605: #include <setjmp.h>
                   9606: #include <unistd.h>            /* getcwd */
                   9607: #include <sys/times.h>
                   9608: #ifdef linux
                   9609: #include <sys/stat.h>
                   9610: #endif
                   9611: #include "sh.h"
                   9612: 
                   9613: static char *   clocktos    ARGS((clock_t t));
                   9614: 
                   9615: #ifndef CLK_TCK
                   9616: #define CLK_TCK 60                     /* 60HZ */
                   9617: #endif
                   9618: 
                   9619: int
                   9620: c_label(wp)
                   9621:        char **wp;
                   9622: {
                   9623:        return 0;
                   9624: }
                   9625: 
                   9626: int
                   9627: c_shift(wp)
                   9628:        register char **wp;
                   9629: {
                   9630:        register struct block *l = e.loc;
                   9631:        register int n;
                   9632: 
                   9633:        n = wp[1] ? evaluate(wp[1]) : 1;
                   9634:        if (l->argc < n) {
                   9635:                errorf("nothing to shift\n");
                   9636:                return (1);
                   9637:        }
                   9638:        l->argv[n] = l->argv[0];
                   9639:        l->argv += n;
                   9640:        l->argc -= n;
                   9641:        return 0;
                   9642: }
                   9643: 
                   9644: int
                   9645: c_umask(wp)
                   9646:        register char **wp;
                   9647: {
                   9648:        register int i;
                   9649:        register char *cp;
                   9650: 
                   9651:        if ((cp = wp[1]) == NULL) {
                   9652:                i = umask(0);
                   9653:                umask(i);
                   9654:                printf("%#3.3o\n", i);  /* should this be shell output? */
                   9655:        } else {
                   9656:                for (i = 0; *cp>='0' && *cp<='7'; cp++)
                   9657:                        i = i*8 + (*cp-'0');
                   9658:                umask(i);
                   9659:        }
                   9660:        return 0;
                   9661: }
                   9662: 
                   9663: int
                   9664: c_dot(wp)
                   9665:        char **wp;
                   9666: {
                   9667:        char *file, *cp;
                   9668: 
                   9669:        if ((cp = wp[1]) == NULL)
                   9670:                return 0;
                   9671:        file = search(cp, path, 0);
                   9672:        if (file == NULL)
                   9673:                errorf("%s: not found\n", cp);
                   9674:        if (include(file))
                   9675:                return exstat;
                   9676:        return -1;
                   9677: }
                   9678: 
                   9679: int
                   9680: c_wait(wp)
                   9681:        char **wp;
                   9682: {
                   9683:        register char *cp;
                   9684: 
                   9685:        wp++;
                   9686:        cp = *wp;
                   9687:        if (cp == NULL) cp = "%";
                   9688:        /* todo: print status ? */
                   9689:        return waitfor(j_lookup(cp));
                   9690: }
                   9691: 
                   9692: int
                   9693: c_read(wp)
                   9694:        register char **wp;
                   9695: {
                   9696:        register int c = 0;
                   9697:        FILE *f = stdin;
                   9698:        int expand = 1;
                   9699:        register char *cp;
                   9700: 
                   9701:        for (wp++; (cp = *wp) != NULL && *cp++ == '-'; wp++) {
                   9702:                while (*cp) switch (*cp++) {
                   9703:                  case 'e':
                   9704:                        expand = 1;
                   9705:                        break;
                   9706:                  case 'r':
                   9707:                        expand = 0;
                   9708:                        break;
                   9709:                  case 'u':
                   9710:                        if (!digit(*cp) || (f = shf[*cp++-'0']) == NULL)
                   9711:                                errorf("bad -u argument\n");
                   9712:                        break;
                   9713:                }
                   9714:        }
                   9715: 
                   9716:        if (*wp == NULL)
                   9717:                errorf("missing name\n");
                   9718:        if ((cp = strchr(*wp, '?')) != NULL) {
                   9719:                *cp = 0;
                   9720:                if (flag[FTALKING]) {
                   9721:                        shellf("%s ", cp+1);
                   9722:                        fflush(shlout);
                   9723:                }
                   9724:        }
                   9725: 
                   9726:        for (; *wp != NULL; wp++) {
                   9727:                for (cp = line; cp <= line+LINE; ) {
                   9728:                        if (c == '\n')
                   9729:                                break;
                   9730:                        c = getc(f);
                   9731:                        if (c == EOF)
                   9732:                                return 1;
                   9733:                        if (expand && c == '\\') {
                   9734:                                c = getc(f);
                   9735:                                if (c == '\n')
                   9736:                                        c = 0;
                   9737:                                else
                   9738:                                        *cp++ = c;
                   9739:                                continue;
                   9740:                        }
                   9741:                        if (c == '\n' || (wp[1] && ctype(c, C_IFS)))
                   9742:                                break;
                   9743:                        *cp++ = c;
                   9744:                }
                   9745:                *cp = 0;
                   9746:                setstr(global(*wp), line);
                   9747:        }
                   9748:        return 0;
                   9749: }
                   9750: 
                   9751: int
                   9752: c_eval(wp)
                   9753:        register char **wp;
                   9754: {
                   9755:        register struct source *s;
                   9756: 
                   9757:        s = pushs(SWORDS);
                   9758:        s->u.strv = wp+1;
                   9759:        return shell(s);
                   9760: }
                   9761: 
                   9762: void setsig ARGS((struct trap *p, handler_t f));
                   9763: 
                   9764: int
                   9765: c_trap(wp)
                   9766:        register char **wp;
                   9767: {
                   9768:        int i;
                   9769:        char *s;
                   9770:        register struct trap *p;
                   9771: 
                   9772:        wp++;
                   9773:        if (*wp == NULL) {
                   9774:                for (p = sigtraps, i = SIGNALS; --i >= 0; p++) {
                   9775:                        if (p->trap != NULL)
                   9776:                                shellf("%s: %s\n", p->name, p->trap);
                   9777:                }
                   9778:                return 0;
                   9779:        }
                   9780: 
                   9781:        s = (gettrap(*wp) == NULL) ? *wp++ : NULL; /* get command */
                   9782:        if (s != NULL && s[0] == '-' && s[1] == '\0')
                   9783:                s = NULL;
                   9784: 
                   9785:        /* set/clear traps */
                   9786:        while (*wp != NULL) {
                   9787:                p = gettrap(*wp++);
                   9788:                if (p == NULL)
                   9789:                        errorf("trap: bad signal %s\n", wp[-1]);
                   9790:                if (p->trap != NULL)
                   9791:                        afree((void*)p->trap, APERM);
                   9792:                p->trap = NULL;
                   9793:                if (s != NULL) {
                   9794:                        if (strlen(s) != 0) {
                   9795:                                p->trap = strsave(s, APERM);
                   9796:                                setsig(p, trapsig);
                   9797:                        } else
                   9798:                                setsig(p, (handler_t)SIG_IGN);
                   9799:                } else
                   9800:                        /* todo: restore to orginal value */
                   9801:                    setsig(p,
                   9802:                       (p->signal==SIGINT || p->signal==SIGQUIT) && flag[FTALKING]
                   9803:                           ? (handler_t)SIG_IGN : (handler_t)SIG_DFL);
                   9804:        }
                   9805:        return 0;
                   9806: }
                   9807: 
                   9808: void
                   9809: setsig(p, f)
                   9810:        register struct trap *p;
                   9811:        void (*f)();
                   9812: {
                   9813:   if (p->signal == 0)
                   9814:     return;
                   9815: #ifdef USE_SIGACT
                   9816:   sigaction(p->signal, &Sigact_ign, &Sigact);
                   9817:   if (Sigact.sa_handler != SIG_IGN || p->ourtrap)
                   9818:   {
                   9819:     p->ourtrap = 1;
                   9820:     Sigact.sa_handler = f;
                   9821:     sigaction(p->signal, &Sigact, NULL);
                   9822:     sigemptyset(&Sigact.sa_mask);
                   9823:     Sigact.sa_flags = 0;
                   9824:   }
                   9825: #else
                   9826:   if (signal(p->signal, SIG_IGN) != SIG_IGN || p->ourtrap)
                   9827:   {
                   9828:     p->ourtrap = 1;
                   9829:     signal(p->signal, f);
                   9830:   }
                   9831: #endif
                   9832: }
                   9833: 
                   9834: int
                   9835: c_return(wp)
                   9836:        char **wp;
                   9837: {
                   9838:        wp++;
                   9839:        if (*wp != NULL)
                   9840:                exstat = getn(*wp);
                   9841:        quitenv();              /* pop E_TCOM */
                   9842:        while (e.type == E_LOOP || e.type == E_EXEC)
                   9843:                quitenv();
                   9844:        if (e.type == E_FUNC)
                   9845:                longjmp(e.jbuf, 1);
                   9846:        leave(exstat);
                   9847: }
                   9848: 
                   9849: int
                   9850: c_brkcont(wp)
                   9851:        register char **wp;
                   9852: {
                   9853:        int quit;
                   9854: 
                   9855:        quit = wp[1] == NULL ? 1 : getn(wp[1]);
                   9856:        quitenv();              /* pop E_TCOM */
                   9857:        while (e.type == E_LOOP || e.type == E_EXEC) {
                   9858:                if (e.type == E_LOOP && --quit <= 0)
                   9859:                        longjmp(e.jbuf, (*wp[0] == 'b') ? LBREAK : LCONTIN);
                   9860:                quitenv();
                   9861:        }
                   9862:        errorf("cannot %s\n", wp[0]);
                   9863: }
                   9864: 
                   9865: 
                   9866: /* 91-05-27 <sjg>
                   9867:  * we are supposed to not exit first try
                   9868:  * if there are stopped jobs.
                   9869:  */
                   9870: int
                   9871: c_exit(wp)
                   9872:        char **wp;
                   9873: {
                   9874:        register char *cp;
                   9875:        static int extry = 0;
                   9876:        
                   9877: #ifdef JOBS
                   9878:        if (extry++ == 0)
                   9879:        {
                   9880:          if (flag[FMONITOR] && j_stopped()) /* todo: only once */
                   9881:          {
                   9882:            errorf("There are stopped jobs\n");
                   9883:            return 1;
                   9884:          }
                   9885:        }
                   9886: #endif
                   9887:        e.oenv = NULL;
                   9888:        if ((cp = wp[1]) != NULL)
                   9889:                exstat = getn(cp);
                   9890:        leave(exstat);
                   9891: }
                   9892: 
                   9893: int
                   9894: c_set(wp)
                   9895:        register char **wp;
                   9896: {
                   9897:        struct block *l = e.loc;
                   9898:        register char **owp = wp;
                   9899:        register char *cp;
                   9900:        int old_fmonitor = flag[FMONITOR];
                   9901: 
                   9902:        if ((cp = *++wp) == NULL) {
                   9903:                static char * const args [] = {"set", "-", NULL};
                   9904:                extern int c_typeset ARGS((char **args));
                   9905:                return c_typeset(args);
                   9906:        }
                   9907:        
                   9908:        for (; (cp = *wp) != NULL && (*cp == '-' || *cp == '+');) {
                   9909:                int i, n = *cp++ == '-'; /* set or clear flag */
                   9910:                wp++;
                   9911:                if (*cp == '\0') {
                   9912:                        if (n)
                   9913:                                flag[FXTRACE] = flag[FVERBOSE] = 0;
                   9914:                        break;
                   9915:                }
                   9916:                if (*cp == '-')
                   9917:                        goto setargs;
                   9918:                for (; *cp != '\0'; cp++)
                   9919:                        if (*cp == 'o') {
                   9920:                                if (*wp == NULL) {
                   9921:                                        printoptions();
                   9922:                                        return 0;
                   9923:                                }
                   9924:                                i = option(*wp++);
                   9925:                                if (i == 0)
                   9926:                                        shellf("%s: unknown option\n", *--wp);
                   9927:                                flag[i] = n;
                   9928:                                if (i == FEMACS && n)
                   9929:                                        flag[FVI] = 0;
                   9930:                                else if (i == FVI && n)
                   9931:                                        flag[FEMACS] = 0;
                   9932:                        } else if (*cp>='a' && *cp<='z')
                   9933:                                flag[FLAG(*cp)] = n;
                   9934:                        else
                   9935:                                errorf("%c: bad flag\n", *cp);
                   9936:                if (flag[FTALKING])
                   9937:                        flag[FERREXIT] = 0;
                   9938:        }
                   9939: 
                   9940: #ifdef JOBS
                   9941:        if (old_fmonitor != flag[FMONITOR])
                   9942:                j_change();
                   9943: #endif
                   9944: 
                   9945:        /* set $# and $* */
                   9946:        if (*wp != NULL) {
                   9947:          setargs:
                   9948:                owp = --wp;
                   9949:                wp[0] = l->argv[0]; /* save $0 */
                   9950:                while (*++wp != NULL)
                   9951:                        *wp = strsave(*wp, &l->area);
                   9952:                l->argc = wp - owp - 1;
                   9953:                l->argv = (char **) alloc(sizeofN(char *, l->argc+2), &l->area);
                   9954:                for (wp = l->argv; (*wp++ = *owp++) != NULL; )
                   9955:                        ;
                   9956:                resetopts();
                   9957:        }
                   9958:        return 0;
                   9959: }
                   9960: 
                   9961: int
                   9962: c_unset(wp)
                   9963:        register char **wp;
                   9964: {
                   9965:        register char *id;
                   9966:        int flagf = 0;
                   9967: 
                   9968:        for (wp++; (id = *wp) != NULL && *id == '-'; wp++)
                   9969:                if (*++id == 'f')
                   9970:                        flagf++;
                   9971:        for (; (id = *wp) != NULL; wp++)
                   9972:                if (!flagf) {   /* unset variable */
                   9973:                        unset(global(id));
                   9974:                } else {        /* unset function */
                   9975:                        define(id, (struct op *)NULL);
                   9976:                }
                   9977:        return 0;
                   9978: }
                   9979: 
                   9980: int
                   9981: c_ulimit(wp)
                   9982:        register char **wp;
                   9983: {
                   9984:        extern int do_ulimit();
                   9985: 
                   9986:        return do_ulimit(wp[1], wp[2]);
                   9987: }
                   9988: 
                   9989: int
                   9990: c_times(wp)
                   9991:        char **wp;
                   9992: {
                   9993:        struct tms all;
                   9994: 
                   9995:        (void) times(&all);
                   9996:        printf("Shell: ");
                   9997:        printf("%8s user ", clocktos(all.tms_utime));
                   9998:        printf("%8s system\n", clocktos(all.tms_stime));
                   9999:        printf("Kids:  ");
                   10000:        printf("%8s user ", clocktos(all.tms_cutime));
                   10001:        printf("%8s system\n", clocktos(all.tms_cstime));
                   10002: 
                   10003:        return 0;
                   10004: }
                   10005: 
                   10006: /*
                   10007:  * time pipeline (really a statement, not a built-in comman)
                   10008:  */
                   10009: int
                   10010: timex(t, f)
                   10011:        struct op *t;
                   10012:        int f;
                   10013: {
                   10014:        int rv;
                   10015:        struct tms t0, t1;
                   10016:        clock_t t0t, t1t;
                   10017:        extern clock_t j_utime, j_stime; /* computed by j_wait */
                   10018: 
                   10019:        j_utime = j_stime = 0;
                   10020:        t0t = times(&t0);
                   10021:        rv = execute(t->left, f);
                   10022:        t1t = times(&t1);
                   10023: 
                   10024:        shellf("%8s real ", clocktos(t1t - t0t));
                   10025:        shellf("%8s user ",
                   10026:               clocktos(t1.tms_utime - t0.tms_utime + j_utime));
                   10027:        shellf("%8s system ",
                   10028:               clocktos(t1.tms_stime - t0.tms_stime + j_stime));
                   10029:        shellf("\n");
                   10030: 
                   10031:        return rv;
                   10032: }
                   10033: 
                   10034: static char *
                   10035: clocktos(t)
                   10036:        clock_t t;
                   10037: {
                   10038:        static char temp[20];
                   10039:        register int i;
                   10040:        register char *cp = temp + sizeof(temp);
                   10041: 
                   10042: #if CLK_TCK != 100             /* convert to 1/100'ths */
                   10043:        t = (t < 1000000000/CLK_TCK) ?
                   10044:                (t * 100) / CLK_TCK : (t / CLK_TCK) * 100;
                   10045: #endif
                   10046: 
                   10047:        *--cp = '\0';
                   10048:        *--cp = 's';
                   10049:        for (i = -2; i <= 0 || t > 0; i++) {
                   10050:                if (i == 0)
                   10051:                        *--cp = '.';
                   10052:                *--cp = '0' + (char)(t%10);
                   10053:                t /= 10;
                   10054:        }
                   10055:        return cp;
                   10056: }
                   10057: 
                   10058: /* dummy function, special case in comexec() */
                   10059: int
                   10060: c_exec(wp)
                   10061:        char ** wp;
                   10062: {
                   10063:        return 0;
                   10064: }
                   10065: 
                   10066: /* dummy function, special case in comexec() */
                   10067: int
                   10068: c_builtin(wp)
                   10069:        char ** wp;
                   10070: {
                   10071:        return 0;
                   10072: }
                   10073: 
                   10074: extern int c_test();           /* in test.c */
                   10075: 
                   10076: const struct builtin shbuiltins [] = {
                   10077:        {"=:", c_label},
                   10078:        {"=.", c_dot},
                   10079:        {"[", c_test},
                   10080:        {"=builtin", c_builtin},
                   10081:        {"=exec", c_exec},
                   10082:        {"=shift", c_shift},
                   10083:        {"=wait", c_wait},
                   10084:        {"read", c_read},
                   10085:        {"=eval", c_eval},
                   10086:        {"=trap", c_trap},
                   10087:        {"=break", c_brkcont},
                   10088:        {"=continue", c_brkcont},
                   10089:        {"=exit", c_exit},
                   10090:        {"=return", c_return},
                   10091:        {"=set", c_set},
                   10092:        {"unset", c_unset},
                   10093:        {"umask", c_umask},
                   10094:        {"test", c_test},
                   10095:        {"=times", c_times},
                   10096:        {"ulimit", c_ulimit},
                   10097:        {NULL, NULL}
                   10098: };
                   10099: 
                   10100: ./pdksh/sh/c_test.c   644    653   1762       16156  5302766312  11475 0ustar  hlu/*
                   10101:  * test(1); version 7-like  --  author Erik Baalbergen
                   10102:  * modified by Eric Gisin to be used as built-in.
                   10103:  * modified by Arnold Robbins to add SVR3 compatibility
                   10104:  * (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket).
                   10105:  */
                   10106: 
                   10107: #ifndef lint
                   10108: static char *RCSid = "$Id: c_test.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   10109: #endif
                   10110: 
                   10111: #include "stdh.h"
                   10112: #include <signal.h>
                   10113: #include <errno.h>
                   10114: #include <setjmp.h>
                   10115: #include <unistd.h>
                   10116: #include <sys/stat.h>
                   10117: #include "sh.h"
                   10118: 
                   10119: /* test(1) accepts the following grammar:
                   10120:        oexpr   ::= aexpr | aexpr "-o" oexpr ;
                   10121:        aexpr   ::= nexpr | nexpr "-a" aexpr ;
                   10122:        nexpr   ::= primary ! "!" primary
                   10123:        primary ::= unary-operator operand
                   10124:                | operand binary-operator operand
                   10125:                | operand
                   10126:                | "(" oexpr ")"
                   10127:                ;
                   10128:        unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
                   10129:                "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
                   10130: 
                   10131:        binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
                   10132:                        "-nt"|"-ot"|"-ef";
                   10133:        operand ::= <any legal UNIX file name>
                   10134: */
                   10135: 
                   10136: #define EOI    0
                   10137: #define FILRD  1
                   10138: #define FILWR  2
                   10139: #define FILREG 3
                   10140: #define FILID  4
                   10141: #define FILGZ  5
                   10142: #define FILTT  6
                   10143: #define STZER  7
                   10144: #define STNZE  8
                   10145: #define STEQL  9
                   10146: #define STNEQ  10
                   10147: #define INTEQ  11
                   10148: #define INTNE  12
                   10149: #define INTGE  13
                   10150: #define INTGT  14
                   10151: #define INTLE  15
                   10152: #define INTLT  16
                   10153: #define UNOT   17
                   10154: #define BAND   18
                   10155: #define BOR    19
                   10156: #define LPAREN 20
                   10157: #define RPAREN 21
                   10158: #define OPERAND        22
                   10159: #define FILEX  23
                   10160: #define FILCDEV        24
                   10161: #define FILBDEV        25
                   10162: #define FILFIFO        26
                   10163: #define FILSETU        27
                   10164: #define FILSETG        28
                   10165: #define FILSTCK        29
                   10166: #define FILSYM 30
                   10167: #define FILNT  31
                   10168: #define FILOT  32
                   10169: #define FILEQ  33
                   10170: #define FILSOCK        34
                   10171: #define        FILUID  35
                   10172: #define        FILGID  36
                   10173: #define        OPTION  37
                   10174: 
                   10175: #define UNOP   1
                   10176: #define BINOP  2
                   10177: #define BUNOP  3
                   10178: #define BBINOP 4
                   10179: #define PAREN  5
                   10180: 
                   10181: struct t_op {
                   10182:        char *op_text;
                   10183:        short op_num, op_type;
                   10184: } const ops [] = {
                   10185:        {"-r",  FILRD,  UNOP},
                   10186:        {"-w",  FILWR,  UNOP},
                   10187:        {"-x",  FILEX,  UNOP},
                   10188:        {"-f",  FILREG, UNOP},
                   10189:        {"-d",  FILID,  UNOP},
                   10190:        {"-c",  FILCDEV,UNOP},
                   10191:        {"-b",  FILBDEV,UNOP},
                   10192:        {"-p",  FILFIFO,UNOP},
                   10193:        {"-u",  FILSETU,UNOP},
                   10194:        {"-g",  FILSETG,UNOP},
                   10195:        {"-k",  FILSTCK,UNOP},
                   10196:        {"-s",  FILGZ,  UNOP},
                   10197:        {"-t",  FILTT,  UNOP},
                   10198:        {"-z",  STZER,  UNOP},
                   10199:        {"-n",  STNZE,  UNOP},
                   10200: #if 0                          /* conficts with binary -o */
                   10201:        {"-o",  OPTION, UNOP},
                   10202: #endif
                   10203:        {"-U",  FILUID, UNOP},
                   10204:        {"-G",  FILGID, UNOP},
                   10205:        {"-L",  FILSYM, UNOP},
                   10206:        {"-S",  FILSOCK,UNOP},
                   10207:        {"=",   STEQL,  BINOP},
                   10208:        {"!=",  STNEQ,  BINOP},
                   10209:        {"-eq", INTEQ,  BINOP},
                   10210:        {"-ne", INTNE,  BINOP},
                   10211:        {"-ge", INTGE,  BINOP},
                   10212:        {"-gt", INTGT,  BINOP},
                   10213:        {"-le", INTLE,  BINOP},
                   10214:        {"-lt", INTLT,  BINOP},
                   10215:        {"-nt", FILNT,  BINOP},
                   10216:        {"-ot", FILOT,  BINOP},
                   10217:        {"-ef", FILEQ,  BINOP},
                   10218:        {"!",   UNOT,   BUNOP},
                   10219:        {"-a",  BAND,   BBINOP},
                   10220:        {"-o",  BOR,    BBINOP},
                   10221:        {"(",   LPAREN, PAREN},
                   10222:        {")",   RPAREN, PAREN},
                   10223:        {0,     0,      0}
                   10224: };
                   10225: 
                   10226: char **t_wp;
                   10227: struct t_op const *t_wp_op;
                   10228: 
                   10229: static void syntax();
                   10230: 
                   10231: int
                   10232: c_test(wp)
                   10233:        char **wp;
                   10234: {
                   10235:        int     res;
                   10236: 
                   10237:        t_wp = wp+1;
                   10238:        if (strcmp(wp[0], "[") == 0) {
                   10239:                while (*wp != NULL)
                   10240:                        wp++;
                   10241:                if (strcmp(*--wp, "]") != 0)
                   10242:                        errorf("[: missing ]\n");
                   10243:                *wp = NULL;
                   10244:        }
                   10245:        res = *t_wp == NULL || !oexpr(t_lex(*t_wp));
                   10246: 
                   10247:        if (*t_wp != NULL && *++t_wp != NULL)
                   10248:                syntax(*t_wp, "unknown operand");
                   10249: 
                   10250:        return res;
                   10251: }
                   10252: 
                   10253: static void
                   10254: syntax(op, msg)
                   10255:        char    *op;
                   10256:        char    *msg;
                   10257: {
                   10258:        if (op && *op)
                   10259:                errorf("test: %s: %s\n", op, msg);
                   10260:        else
                   10261:                errorf("test: %s\n", msg);
                   10262: }
                   10263: 
                   10264: oexpr(n)
                   10265: {
                   10266:        int res;
                   10267: 
                   10268:        res = aexpr(n);
                   10269:        if (t_lex(*++t_wp) == BOR)
                   10270:                return oexpr(t_lex(*++t_wp)) || res;
                   10271:        t_wp--;
                   10272:        return res;
                   10273: }
                   10274: 
                   10275: aexpr(n)
                   10276: {
                   10277:        int res;
                   10278: 
                   10279:        res = nexpr(n);
                   10280:        if (t_lex(*++t_wp) == BAND)
                   10281:                return aexpr(t_lex(*++t_wp)) && res;
                   10282:        t_wp--;
                   10283:        return res;
                   10284: }
                   10285: 
                   10286: nexpr(n)
                   10287:        int n;                  /* token */
                   10288: {
                   10289:        if (n == UNOT)
                   10290:                return !nexpr(t_lex(*++t_wp));
                   10291:        return primary(n);
                   10292: }
                   10293: 
                   10294: primary(n)
                   10295:        int n;                  /* token */
                   10296: {
                   10297:        register char *opnd1, *opnd2;
                   10298:        int res;
                   10299: 
                   10300:        if (n == EOI)
                   10301:                syntax(NULL, "argument expected");
                   10302:        if (n == LPAREN) {
                   10303:                res = oexpr(t_lex(*++t_wp));
                   10304:                if (t_lex(*++t_wp) != RPAREN)
                   10305:                        syntax(NULL, "closing paren expected");
                   10306:                return res;
                   10307:        }
                   10308:        if (t_wp_op && t_wp_op->op_type == UNOP) {
                   10309:                /* unary expression */
                   10310:                if (*++t_wp == NULL && n != FILTT)
                   10311:                        syntax(t_wp_op->op_text, "argument expected");
                   10312:                switch (n) {
                   10313:                  case OPTION:
                   10314:                        return flag[option(*t_wp)];
                   10315:                  case STZER:
                   10316:                        return strlen(*t_wp) == 0;
                   10317:                  case STNZE:
                   10318:                        return strlen(*t_wp) != 0;
                   10319:                  case FILTT:
                   10320:                        if (!digit(**t_wp))
                   10321:                                return filstat("0", n);
                   10322:                  default:      /* all other FIL* */
                   10323:                        return filstat(*t_wp, n);
                   10324:                }
                   10325:        }
                   10326:        opnd1 = *t_wp;
                   10327:        (void) t_lex(*++t_wp);
                   10328:        if (t_wp_op && t_wp_op->op_type == BINOP) {
                   10329:                struct t_op const *op = t_wp_op;
                   10330: 
                   10331:                if ((opnd2 = *++t_wp) == (char *)0)
                   10332:                        syntax(op->op_text, "argument expected");
                   10333:                
                   10334:                switch (op->op_num) {
                   10335:                case STEQL:
                   10336:                        return strcmp(opnd1, opnd2) == 0;
                   10337:                case STNEQ:
                   10338:                        return strcmp(opnd1, opnd2) != 0;
                   10339:                case INTEQ:
                   10340:                        return evaluate(opnd1) == evaluate(opnd2);
                   10341:                case INTNE:
                   10342:                        return evaluate(opnd1) != evaluate(opnd2);
                   10343:                case INTGE:
                   10344:                        return evaluate(opnd1) >= evaluate(opnd2);
                   10345:                case INTGT:
                   10346:                        return evaluate(opnd1) > evaluate(opnd2);
                   10347:                case INTLE:
                   10348:                        return evaluate(opnd1) <= evaluate(opnd2);
                   10349:                case INTLT:
                   10350:                        return evaluate(opnd1) < evaluate(opnd2);
                   10351:                case FILNT:
                   10352:                        return newerf (opnd1, opnd2);
                   10353:                case FILOT:
                   10354:                        return olderf (opnd1, opnd2);
                   10355:                case FILEQ:
                   10356:                        return equalf (opnd1, opnd2);
                   10357:                }
                   10358:        }
                   10359:        t_wp--;
                   10360:        return strlen(opnd1) > 0;
                   10361: }
                   10362: 
                   10363: filstat(nm, mode)
                   10364:        char *nm;
                   10365: {
                   10366:        struct stat s;
                   10367:        
                   10368:        switch (mode) {
                   10369:        case FILRD:
                   10370:                return eaccess(nm, 4) == 0;
                   10371:        case FILWR:
                   10372:                return eaccess(nm, 2) == 0;
                   10373:        case FILEX:
                   10374:                return eaccess(nm, 1) == 0;
                   10375:        case FILREG:
                   10376:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFREG;
                   10377:        case FILID:
                   10378:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFDIR;
                   10379:        case FILCDEV:
                   10380:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFCHR;
                   10381:        case FILBDEV:
                   10382:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFBLK;
                   10383:        case FILFIFO:
                   10384: #ifdef S_IFIFO
                   10385:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFIFO;
                   10386: #else
                   10387:                return 0;
                   10388: #endif
                   10389:        case FILSETU:
                   10390:                return stat(nm, &s) == 0 && (s.st_mode & S_ISUID) == S_ISUID;
                   10391:        case FILSETG:
                   10392:                return stat(nm, &s) == 0 && (s.st_mode & S_ISGID) == S_ISGID;
                   10393:        case FILSTCK:
                   10394:                return stat(nm, &s) == 0 && (s.st_mode & S_ISVTX) == S_ISVTX;
                   10395:        case FILGZ:
                   10396:                return stat(nm, &s) == 0 && s.st_size > 0L;
                   10397:        case FILTT:
                   10398:                return isatty(getn(nm));
                   10399:          case FILUID:
                   10400:                return stat(nm, &s) == 0 && s.st_uid == geteuid();
                   10401:          case FILGID:
                   10402:                return stat(nm, &s) == 0 && s.st_gid == getegid();
                   10403: #ifdef S_IFLNK
                   10404:        case FILSYM:
                   10405:                return lstat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFLNK;
                   10406: #endif
                   10407: #ifdef S_IFSOCK
                   10408:        case FILSOCK:
                   10409:                return stat(nm, &s) == 0 && (s.st_mode & S_IFMT) == S_IFSOCK;
                   10410: #endif
                   10411:          default:
                   10412:                return 1;
                   10413:        }
                   10414: }
                   10415: 
                   10416: int
                   10417: t_lex(s)
                   10418:        register char *s;
                   10419: {
                   10420:        register struct t_op const *op = ops;
                   10421: 
                   10422:        if (s == 0) {
                   10423:                t_wp_op = (struct t_op *)0;
                   10424:                return EOI;
                   10425:        }
                   10426:        while (op->op_text) {
                   10427:                if (strcmp(s, op->op_text) == 0) {
                   10428:                        t_wp_op = op;
                   10429:                        return op->op_num;
                   10430:                }
                   10431:                op++;
                   10432:        }
                   10433:        t_wp_op = (struct t_op *)0;
                   10434:        return OPERAND;
                   10435: }
                   10436: 
                   10437: newerf (f1, f2)
                   10438: char *f1, *f2;
                   10439: {
                   10440:        struct stat b1, b2;
                   10441: 
                   10442:        return (stat (f1, &b1) == 0 &&
                   10443:                stat (f2, &b2) == 0 &&
                   10444:                b1.st_mtime > b2.st_mtime);
                   10445: }
                   10446: 
                   10447: olderf (f1, f2)
                   10448: char *f1, *f2;
                   10449: {
                   10450:        struct stat b1, b2;
                   10451: 
                   10452:        return (stat (f1, &b1) == 0 &&
                   10453:                stat (f2, &b2) == 0 &&
                   10454:                b1.st_mtime < b2.st_mtime);
                   10455: }
                   10456: 
                   10457: equalf (f1, f2)
                   10458: char *f1, *f2;
                   10459: {
                   10460:        struct stat b1, b2;
                   10461: 
                   10462:        return (stat (f1, &b1) == 0 &&
                   10463:                stat (f2, &b2) == 0 &&
                   10464:                b1.st_dev == b2.st_dev &&
                   10465:                b1.st_ino == b2.st_ino);
                   10466: }
                   10467: 
                   10468: ./pdksh/sh/edit.c   644    653   1762       22023  5243743652  11135 0ustar  hlu/*
                   10469:  * Command line editing - common code
                   10470:  *
                   10471:  */
                   10472: 
                   10473: #include "config.h"
                   10474: #if defined(EMACS) || defined(VI)
                   10475: 
                   10476: #ifndef lint
                   10477: static char *RCSid = "$Id: edit.c,v 1.5 1992/08/10 12:02:25 sjg Exp $";
                   10478: #endif
                   10479: 
                   10480: #include "stdh.h"
                   10481: #include <unistd.h>
                   10482: #include <signal.h>
                   10483: #include <fcntl.h>
                   10484: #include <errno.h>
                   10485: #include <setjmp.h>
                   10486: #ifndef NOSTDHDRS
                   10487: # include <string.h>
                   10488: #endif
                   10489: #include "sh.h"
                   10490: #include "tty.h"
                   10491: #define EXTERN
                   10492: #include "edit.h"
                   10493: #undef EXTERN
                   10494: 
                   10495: #ifdef _CRAY2
                   10496: extern unsigned        sleep();
                   10497: #endif
                   10498: 
                   10499: 
                   10500: static int     x_noecho = 0;
                   10501: 
                   10502: /*
                   10503:  * read an edited command line
                   10504:  */
                   10505: int
                   10506: x_read(fd, buf, len)
                   10507:        int fd;                 /* not used */
                   10508:        char *buf;
                   10509:        size_t len;
                   10510: {
                   10511:   static int setup_done = 0;
                   10512:        int     i;
                   10513: 
                   10514:   if (setup_done != 42)
                   10515:   {
                   10516:     setup_done = 42;           /* these get done once only */
                   10517:     x_do_init = 1;
                   10518:     x_col = 0;
                   10519:     ed_erase = -1, ed_kill = -1, ed_werase = -1, ed_intr = -1, ed_quit = -1;
                   10520:     x_adj_ok = 1;
                   10521:     x_adj_done = 0;
                   10522:   }
                   10523:        if (x_do_init)
                   10524:                x_init();
                   10525: 
                   10526:        if (x_noecho)
                   10527:                return(read(ttyfd, buf, len));
                   10528: 
                   10529:        (void)x_mode(TRUE);
                   10530: #ifdef EMACS
                   10531:        if (flag[FEMACS])
                   10532:                i = x_emacs(buf, len);
                   10533:        else
                   10534: #endif
                   10535: #ifdef VI
                   10536:        if (flag[FVI])
                   10537:                i = x_vi(buf, len);
                   10538:        else
                   10539: #endif
                   10540:                i = -1;         /* internal error */
                   10541:        (void) x_mode(FALSE);
                   10542:        if (i > 4 && strstr(buf, "stty"))
                   10543:                x_do_init = 1;
                   10544:        if (i < 0 && errno == EINTR)
                   10545:                trapsig(SIGINT);
                   10546:        return i;
                   10547: }
                   10548: 
                   10549: /* tty I/O */
                   10550: 
                   10551: int
                   10552: x_getc()
                   10553: {
                   10554:   char c;
                   10555: 
                   10556:   /*
                   10557:    * This allows the arival of a SIGCHLD to not disturb us until 
                   10558:    * we are ready. 
                   10559:    * BSD and other systems that automatically rety a read after 
                   10560:    * an interrupt don't need this but it doesn't do any harm 
                   10561:    * either. 
                   10562:    */
                   10563:  retry:
                   10564:        if (read(ttyfd, &c, 1) != 1)
                   10565:        {
                   10566:          if (sigchld_caught)           /* just a SIGCHLD ? */
                   10567:          {
                   10568:            goto retry;
                   10569:          }
                   10570:          return -1;
                   10571:        }
                   10572:        return c & 0x7F;
                   10573: }
                   10574: 
                   10575: void
                   10576: x_flush()
                   10577: {
                   10578:        fflush(stdout);
                   10579: }
                   10580: 
                   10581: 
                   10582: /* NAME:
                   10583:  *      x_adjust - redraw the line adjusting starting point etc.
                   10584:  *
                   10585:  * DESCRIPTION:
                   10586:  *      This function is called when we have exceeded the bounds 
                   10587:  *      of the edit window.  It increments x_adj_done so that 
                   10588:  *      functions like x_ins and x_delete know that we have been 
                   10589:  *      called and can skip the x_bs() stuff which has already 
                   10590:  *      been done by x_redraw.
                   10591:  *
                   10592:  * RETURN VALUE:
                   10593:  *      None
                   10594:  */
                   10595: 
                   10596: void
                   10597: x_adjust()
                   10598: {
                   10599:   x_adj_done++;                        /* flag the fact that we were called. */
                   10600: #ifdef EMACS
                   10601:   /*
                   10602:    * we had a promblem if the prompt length > x_cols / 2
                   10603:    */
                   10604:   if ((xbp = xcp - (x_displen / 2)) < xbuf)
                   10605:     xbp = xbuf;
                   10606:   xlp_valid = FALSE;
                   10607:   x_redraw(x_cols);
                   10608: #endif
                   10609:   x_flush();
                   10610: }
                   10611: 
                   10612: void
                   10613: x_putc(c)
                   10614:        int c;
                   10615: {
                   10616:   if (c == '\r' || c == '\n')
                   10617:     x_col = 0;
                   10618:   if (x_col < x_cols)
                   10619:   {
                   10620:     putc(c, stdout);
                   10621:     switch(c)
                   10622:     {
                   10623:     case BEL:
                   10624:       break;
                   10625:     case '\r':
                   10626:     case '\n':
                   10627:     break;
                   10628:     case '\b':
                   10629:       x_col--;
                   10630:       break;
                   10631:     default:
                   10632:       x_col++;
                   10633:       break;
                   10634:     }
                   10635:   }
                   10636:   if (x_adj_ok && (x_col < 0 || x_col >= (x_cols - 2)))
                   10637:   {
                   10638:     x_adjust();
                   10639:   }
                   10640: }
                   10641: 
                   10642: #ifdef DEBUG
                   10643: int
                   10644: x_debug_info()
                   10645: {
                   10646:   x_flush();
                   10647:   printf("\nksh debug:\n");
                   10648:   printf("\tx_col == %d,\t\tx_cols == %d,\tx_displen == %d\n",
                   10649:         x_col, x_cols, x_displen);
                   10650:   printf("\txcp == 0x%lx,\txep == 0x%lx\n", (long) xcp, (long) xep);
                   10651:   printf("\txbp == 0x%lx,\txbuf == 0x%lx\n", (long) xbp, (long) xbuf);
                   10652:   printf("\txlp == 0x%lx\n", (long) xlp);
                   10653:   printf("\txlp == 0x%lx\n", (long) x_lastcp());
                   10654:   printf("\n");
                   10655:   x_redraw(-1);
                   10656:   return 0;
                   10657: }
                   10658: #endif
                   10659: 
                   10660: void
                   10661: x_puts(s)
                   10662:        register char *s;
                   10663: {
                   10664:   register int adj = x_adj_done;
                   10665: 
                   10666:   while (*s && adj == x_adj_done)
                   10667:     x_putc(*s++);
                   10668: }
                   10669: 
                   10670: #ifdef _BSD
                   10671: static struct sgttyb cb, cborig;
                   10672: #ifdef TIOCGATC
                   10673: static struct ttychars lchars, lcharsorig;
                   10674: #else
                   10675: static struct tchars tchars, tcharsorig;
                   10676: #ifdef TIOCGLTC
                   10677: static struct ltchars ltchars, ltcharsorig;
                   10678: #endif
                   10679: #endif
                   10680: #else
                   10681: #ifdef _POSIX_TERM
                   10682: static struct termios cb, cborig;
                   10683: #else
                   10684: static struct termio cb, cborig;
                   10685: #endif
                   10686: #endif
                   10687: 
                   10688: /* initialize editing mode */
                   10689: void
                   10690: x_init()
                   10691: {
                   10692:        x_do_init = 0;
                   10693: #ifdef _BSD
                   10694:        (void)ioctl(ttyfd, TIOCGETP, &cborig);
                   10695:        if ((cborig.sg_flags & ECHO) == 0)
                   10696:                x_noecho = 1;
                   10697:        cb = cborig;
                   10698:        ed_erase = cb.sg_erase;
                   10699:        ed_kill = cb.sg_kill;
                   10700:        cb.sg_flags &= ~ECHO;
                   10701:        cb.sg_flags |= CBREAK;
                   10702: #ifdef TIOCGATC
                   10703:        (void)ioctl(ttyfd, TIOCGATC, &lcharsorig);
                   10704:        lchars = lcharsorig;
                   10705:        ed_werase = lchars.tc_werasc;
                   10706:        lchars.tc_suspc = -1;
                   10707:        lchars.tc_dsuspc = -1;
                   10708:        lchars.tc_lnextc = -1;
                   10709:        lchars.tc_statc = -1;
                   10710:        lchars.tc_intrc = -1;
                   10711:        lchars.tc_quitc = -1;
                   10712:        lchars.tc_rprntc = -1;
                   10713: #else
                   10714:        (void)ioctl(ttyfd, TIOCGETC, &tcharsorig);
                   10715: #ifdef TIOCGLTC
                   10716:        (void)ioctl(ttyfd, TIOCGLTC, &ltcharsorig);
                   10717: #endif
                   10718:        tchars = tcharsorig;
                   10719: #ifdef TIOCGLTC
                   10720:        ltchars = ltcharsorig;
                   10721:        ed_werase = ltchars.t_werasc;
                   10722:        ltchars = ltcharsorig;
                   10723:        ltchars.t_suspc = -1;
                   10724:        ltchars.t_dsuspc = -1;
                   10725:        ltchars.t_lnextc = -1;
                   10726: #endif
                   10727:        tchars.t_intrc = -1;
                   10728:        tchars.t_quitc = -1;
                   10729: #ifdef TIOCGLTC
                   10730:        ltchars.t_rprntc = -1;
                   10731: #endif
                   10732: #endif
                   10733: #else /* !_BSD */
                   10734: #ifdef _POSIX_TERM
                   10735:        (void) tcgetattr(ttyfd, &cborig);
                   10736: #else
                   10737:        (void)ioctl(ttyfd, TCGETA, &cborig);
                   10738: #endif
                   10739:        if ((cborig.c_lflag & ECHO) == 0)
                   10740:                x_noecho = 1;
                   10741:        cb = cborig;
                   10742:        ed_erase = cb.c_cc[VERASE]; /* TODO */
                   10743:        ed_kill = cb.c_cc[VKILL]; /* TODO */
                   10744:        ed_intr = cb.c_cc[VINTR];
                   10745:        ed_quit = cb.c_cc[VQUIT];
                   10746: #ifdef _CRAY2          /* brain-damaged terminal handler */
                   10747:        cb.c_lflag &= ~(ICANON|ECHO);
                   10748:        /* rely on print routine to map '\n' to CR,LF */
                   10749: #else
                   10750:        cb.c_iflag &= ~(INLCR|ICRNL);
                   10751: #ifdef _BSD_SYSV       /* need to force CBREAK instead of RAW (need CRMOD on output) */
                   10752:        cb.c_lflag &= ~(ICANON|ECHO);
                   10753: #else
                   10754: #ifdef SWTCH   /* need CBREAK to handle swtch char */
                   10755:        cb.c_lflag &= ~(ICANON|ECHO);
                   10756:        cb.c_lflag |= ISIG;
                   10757:        cb.c_cc[VINTR] = 0377;
                   10758:        cb.c_cc[VQUIT] = 0377;
                   10759: #else
                   10760:        cb.c_lflag &= ~(ISIG|ICANON|ECHO);
                   10761: #endif
                   10762: #endif
                   10763:        cb.c_cc[VTIME] = 0;
                   10764:        cb.c_cc[VMIN] = 1;
                   10765: #endif /* _CRAY2 */
                   10766: #endif
                   10767: #ifdef EMACS
                   10768:        x_emacs_keys(ed_erase, ed_kill, ed_werase, ed_intr, ed_quit);
                   10769: #endif
                   10770: }
                   10771: 
                   10772: static bool_t  x_cur_mode = FALSE;
                   10773: 
                   10774: /* set/clear tty cbreak mode */
                   10775: 
                   10776: #ifdef _BSD
                   10777: bool_t
                   10778: x_mode(onoff)
                   10779:        bool_t  onoff;
                   10780: {
                   10781:        bool_t  prev;
                   10782: 
                   10783:        if (x_cur_mode == onoff) return x_cur_mode;
                   10784:        prev = x_cur_mode;
                   10785:        x_cur_mode = onoff;
                   10786:        if (onoff)  {
                   10787:                (void)ioctl(ttyfd, TIOCSETN, &cb);
                   10788: #ifdef TIOCGATC
                   10789:                (void)ioctl(ttyfd, TIOCSATC, &lchars);
                   10790: #else
                   10791:                (void)ioctl(ttyfd, TIOCSETC, &tchars);
                   10792: #ifdef TIOCGLTC
                   10793:                (void)ioctl(ttyfd, TIOCSLTC, &ltchars);
                   10794: #endif
                   10795: #endif
                   10796:        }
                   10797:        else {
                   10798:                (void)ioctl(ttyfd, TIOCSETN, &cborig);
                   10799: #ifdef TIOCGATC
                   10800:                (void)ioctl(ttyfd, TIOCSATC, &lcharsorig);
                   10801: #else
                   10802:                (void)ioctl(ttyfd, TIOCSETC, &tcharsorig);
                   10803: #ifdef TIOCGLTC
                   10804:                (void)ioctl(ttyfd, TIOCSLTC, &ltcharsorig);
                   10805: #endif
                   10806: #endif
                   10807:        }
                   10808:        return prev;
                   10809: }
                   10810: 
                   10811: #else  /* !_BSD */
                   10812: 
                   10813: bool_t
                   10814: x_mode(onoff)
                   10815: bool_t onoff;
                   10816: {
                   10817:        bool_t  prev;
                   10818: 
                   10819:        if (x_cur_mode == onoff) return x_cur_mode;
                   10820:        prev = x_cur_mode;
                   10821:        x_cur_mode = onoff;
                   10822: 
                   10823:        if (onoff)  {
                   10824: #ifdef _POSIX_TERM
                   10825:                (void) tcsetattr(ttyfd, TCSADRAIN, &cb);
                   10826: #else
                   10827: #ifndef TCSETAW                                /* e.g. Cray-2 */
                   10828:                /* first wait for output to drain */
                   10829: #ifdef TCSBRK
                   10830:                (void)ioctl(ttyfd, TCSBRK, 1);
                   10831: #else  /* the following kludge is minimally intrusive, but sometimes fails */
                   10832:                (void)sleep((unsigned)1);       /* fake it */
                   10833: #endif
                   10834: #endif
                   10835: #if defined(_BSD_SYSV) || !defined(TCSETAW)
                   10836: /* _BSD_SYSV needs to force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
                   10837:                (void)ioctl(ttyfd, TCSETA, &cb);
                   10838: #else
                   10839:                (void)ioctl(ttyfd, TCSETAW, &cb);
                   10840: #endif
                   10841: #endif
                   10842:        }
                   10843:        else {
                   10844: #ifdef _POSIX_TERM
                   10845:                (void) tcsetattr(ttyfd, TCSADRAIN, &cborig);
                   10846: #else
                   10847: #ifndef TCSETAW                                /* e.g. Cray-2 */
                   10848:                /* first wait for output to drain */
                   10849: #ifdef TCSBRK
                   10850:                (void)ioctl(ttyfd, TCSBRK, 1);
                   10851: #else
                   10852: /* doesn't seem to be necessary when leaving xmode */
                   10853: /*             (void)sleep((unsigned)1);       /* fake it */
                   10854: #endif
                   10855: #endif
                   10856: #if defined(_BSD_SYSV) || !defined(TCSETAW)
                   10857: /* _BSD_SYSV needs to force TIOCSETN instead of TIOCSETP (preserve type-ahead) */
                   10858:                (void)ioctl(ttyfd, TCSETA, &cborig);
                   10859: #else
                   10860:                (void)ioctl(ttyfd, TCSETAW, &cborig);
                   10861: #endif
                   10862: #endif
                   10863:        }
                   10864:        return prev;
                   10865: }
                   10866: #endif /* _BSD */
                   10867: 
                   10868: 
                   10869: /* NAME:
                   10870:  *      promptlen - calculate the length of PS1 etc.
                   10871:  *
                   10872:  * DESCRIPTION:
                   10873:  *      This function is based on a fix from [email protected]
                   10874:  *      It fixes a bug in that if PS1 contains '!', the length 
                   10875:  *      given by strlen() is probably wrong.
                   10876:  *
                   10877:  * RETURN VALUE:
                   10878:  *      length
                   10879:  */
                   10880:  
                   10881: int
                   10882: promptlen(cp)
                   10883:   register char  *cp;
                   10884: {
                   10885:   register int count = 0;
                   10886: 
                   10887:   while (*cp)
                   10888:   {
                   10889:     if ( *cp++ != '!' )
                   10890:       count++;
                   10891:     else
                   10892:       if ( *cp == '!' )
                   10893:       {
                   10894:        cp++;
                   10895:        count++;
                   10896:       }
                   10897:       else
                   10898:       {
                   10899:        register int i = source->line;
                   10900: 
                   10901:        do
                   10902:        {
                   10903:          count ++;
                   10904:        }
                   10905:        while( ( i /= 10 ) > 0 );
                   10906:       }
                   10907:   }
                   10908:   return count;
                   10909: }
                   10910: 
                   10911: 
                   10912: /*
                   10913:  * this function check the environment
                   10914:  * for FCEDIT,EDITOR or VISUAL
                   10915:  * as a hint to what edit mode is desired.
                   10916:  */
                   10917: init_editmode()
                   10918: {
                   10919:   static char *ev[] = { "FCEDIT", "EDITOR", "VISUAL", NULL };
                   10920:   register int i;
                   10921:   register char *rcp;
                   10922: 
                   10923:   for (i = 0; ev[i]; i++)
                   10924:   {
                   10925: #ifdef DEBUG
                   10926:     (void) fprintf(stderr, "check %s\n", ev[i]);
                   10927: #endif
                   10928:     if ((rcp = strval(global(ev[i]))) && *rcp)
                   10929:       break;
                   10930:   }
                   10931:   if (ev[i] && rcp)
                   10932:   {
                   10933:     set_editmode(rcp);
                   10934:   }
                   10935:   return 0;
                   10936: }
                   10937: 
                   10938: void
                   10939: set_editmode(ed)
                   10940:   char *ed;
                   10941: {
                   10942:   register char *rcp;
                   10943:   
                   10944: #ifdef DEBUG
                   10945:   (void) fprintf(stderr, "set_editmode(%s)\n", ed);
                   10946: #endif
                   10947:   if (rcp = strrchr(ed, '/'))
                   10948:     ed = ++rcp;
                   10949: #ifdef EMACS
                   10950:   if (strstr(ed, "emacs"))
                   10951:   {
                   10952:     flag[FVI] = 0;
                   10953:     flag[FEMACS] = 1;
                   10954:   }
                   10955: #endif
                   10956: #if defined(EMACS) && defined(VI)
                   10957:   else
                   10958: #endif
                   10959: #ifdef VI
                   10960:     if (strstr(ed, "vi"))
                   10961:     {
                   10962:       flag[FVI] = 1;
                   10963:       flag[FEMACS] = 0;
                   10964:     }
                   10965: #endif
                   10966: }
                   10967: #endif
                   10968: ./pdksh/sh/history.c   644    653   1762       43137  5243743676  11730 0ustar  hlu/*
                   10969:  * command history
                   10970:  *
                   10971:  * only implements in-memory history.
                   10972:  */
                   10973: 
                   10974: #ifndef lint
                   10975: static char *RCSid = "$Id: history.c,v 1.4 1992/08/12 14:15:33 sjg Exp $";
                   10976: #endif
                   10977: /*
                   10978:  *     This file contains
                   10979:  *     a)      the original in-memory history  mechanism
                   10980:  *     b)      a simple file saving history mechanism done by  sjg@zen
                   10981:  *             define EASY_HISTORY to get this
                   10982:  *     c)      a more complicated mechanism done by  [email protected]
                   10983:  *             that more closely follows the real ksh way of doing
                   10984:  *             things. You need to have the mmap system call for this
                   10985:  *             to work on your system
                   10986:  */
                   10987: 
                   10988: #include "config.h"
                   10989: #include "stdh.h"
                   10990: 
                   10991: #ifdef EASY_HISTORY
                   10992: 
                   10993: #include <errno.h>
                   10994: #include <setjmp.h>
                   10995: #include "sh.h"
                   10996: 
                   10997: static FILE *hist_fh = NULL;
                   10998: static FILE *hist_open ARGS((char *mode));
                   10999: #ifndef HISTFILE
                   11000: # define HISTFILE ".pdksh_hist"
                   11001: #endif
                   11002: 
                   11003: #else
                   11004: /*     Defines and includes for the complicated case */
                   11005: 
                   11006: #include <sys/types.h>
                   11007: #include <sys/stat.h>
                   11008: #include <sys/file.h>
                   11009: #include <sys/mman.h>
                   11010: #include <errno.h>
                   11011: #include <setjmp.h>
                   11012: #include "sh.h"
                   11013: 
                   11014: /*
                   11015:  *     variables for handling the data file
                   11016:  */
                   11017: static char    *hname;
                   11018: static int     histfd;
                   11019: static int     hsize;
                   11020: static int     hstarted;
                   11021: 
                   11022: static int hist_count_lines ARGS((unsigned char *, int));
                   11023: static int hist_shrink ARGS((unsigned char *, int));
                   11024: static unsigned char *hist_skip_back ARGS((unsigned char *,int *,int));
                   11025: static void histload ARGS((Source *, unsigned char *, int));
                   11026: static void histinsert ARGS((Source *, int, unsigned char *));
                   11027: static void writehistfile ARGS((int, char *));
                   11028: static int sprinkle ARGS((int));
                   11029: 
                   11030: #ifdef MAP_FILE
                   11031: #define        MAP_FLAGS       MAP_FILE|MAP_PRIVATE
                   11032: #else
                   11033: #define        MAP_FLAGS       MAP_PRIVATE
                   11034: #endif
                   11035: 
                   11036: #endif /* of EASY_HISTORY */
                   11037: 
                   11038:   
                   11039: char   *histrpl();
                   11040: char  **current;
                   11041: int    curpos;
                   11042: 
                   11043: c_fc(wp)
                   11044:        register char **wp;
                   11045: {
                   11046:        register char *id;
                   11047:        FILE *f;
                   11048:        struct temp *tf;
                   11049:        register char **hp;
                   11050:        char **hbeg, **hend;
                   11051:        char *p, *cmd = NULL;
                   11052:        int lflag = 0, nflag = 0, sflag = 0, rflag = 0, gflag = 0;
                   11053:        int done = 0;
                   11054:        void histbackup();
                   11055: 
                   11056:        for (wp++; (id = *wp) != NULL && *id++ == '-' && !done; wp++)
                   11057:                while (*id && !done) {
                   11058:                        switch (*id++) {
                   11059:                          case 'l':
                   11060:                                lflag++;
                   11061:                                break;
                   11062:                          case 'n':
                   11063:                                nflag++;
                   11064:                                break;
                   11065:                          case 'r':
                   11066:                                rflag++;
                   11067:                                break;
                   11068:                          case 'g':
                   11069:                                gflag++;
                   11070:                                break;
                   11071:                          case 'e':
                   11072:                                if (++wp && (p = *wp)) {
                   11073:                                        if (p[0] == '-' && !p[1]) {
                   11074:                                                sflag++;
                   11075:                                        } else {
                   11076:                                                cmd = alloc((size_t)(strlen(p)+4),ATEMP);
                   11077:                                                strcpy(cmd, p);
                   11078:                                                strcat(cmd, " $_");
                   11079:                                        }
                   11080:                                } else
                   11081:                                        errorf("argument expected\n");
                   11082:                                id = "";
                   11083:                                break;
                   11084:                          default:
                   11085:                                wp--;
                   11086:                                done++;
                   11087:                                break;
                   11088:                        }
                   11089:                }
                   11090: 
                   11091:        if (sflag) {
                   11092:                char *pat = NULL, *rep = NULL;
                   11093: 
                   11094:                hp = histptr - 1;
                   11095:                while ((id = *wp++) != NULL) {
                   11096:                        /* todo: multiple substitutions */
                   11097:                        if ((p = strchr(id, '=')) != NULL) {
                   11098:                                pat = id;
                   11099:                                rep = p;
                   11100:                                *rep++ = '\0';
                   11101:                        } else
                   11102:                                hp = histget(id);
                   11103:                }
                   11104: 
                   11105:                if (hp == NULL || hp < history)
                   11106:                        errorf("cannot find history\n");
                   11107:                if (pat == NULL)
                   11108:                        strcpy(line, *hp);
                   11109:                else
                   11110:                        histrpl(*hp, pat, rep, gflag);
                   11111:                histbackup();
                   11112: #ifdef EASY_HISTORY
                   11113:                histsave(line); 
                   11114: #else
                   11115:                histsave(source->line+1, line, 1);
                   11116: #endif
                   11117:                histpush--; 
                   11118:                line[0] = '\0';
                   11119:                return 0;
                   11120:        }
                   11121: 
                   11122:        if (*wp != NULL) {
                   11123:                hbeg = histget(*wp++); /* first */
                   11124:                if (*wp != NULL)
                   11125:                        hend = histget(*wp++); /* last */
                   11126:                else if (lflag)
                   11127:                        hend = histptr;
                   11128:                else
                   11129:                        hend = hbeg;
                   11130:        } else {
                   11131:                if (lflag)
                   11132:                        hbeg = histptr - 16, hend = histptr;
                   11133:                else
                   11134:                        hbeg = hend = histptr - 1;
                   11135:                if (hbeg < history)
                   11136:                        hbeg = history;
                   11137:        }
                   11138:        if (hbeg == NULL || hend == NULL)
                   11139:                errorf("can't find history\n");
                   11140: 
                   11141:        if (lflag)
                   11142:                f = stdout;
                   11143:        else {
                   11144:                nflag++;
                   11145:                tf = maketemp(ATEMP);
                   11146:                tf->next = e.temps; e.temps = tf;
                   11147:                f = fopen(tf->name, "w");
                   11148:                if (f == NULL)
                   11149:                        errorf("cannot create temp file %s", tf->name);
                   11150:                setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
                   11151:        }
                   11152: 
                   11153:        for (hp = (rflag ? hend : hbeg); rflag ? (hp >= hbeg) : (hp <= hend);
                   11154:              rflag ? hp-- : hp++) {
                   11155:                if (!nflag)
                   11156:                        fprintf(f, "%3d: ", source->line - (int)(histptr-hp));
                   11157:                fprintf(f, "%s\n", *hp);
                   11158:        }
                   11159: 
                   11160:        if (lflag)
                   11161:                return 0;
                   11162:        else
                   11163:                fclose(f);
                   11164: 
                   11165:        setstr(local("_"), tf->name);
                   11166:        if (cmd) {
                   11167:                command(cmd); /* edit temp file */
                   11168:                afree(cmd, ATEMP);
                   11169:        } else
                   11170:                command("${FCEDIT:-/bin/ed} $_");
                   11171: 
                   11172:        f = fopen(tf->name, "r");
                   11173:        if (f == NULL)
                   11174:                errorf("cannot open temp file %s\n", tf->name);
                   11175:        setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
                   11176:        /* we push the editted lines onto the history list */
                   11177:        while (fgets(line, sizeof(line), f) != NULL) {
                   11178: #ifdef EASY_HISTORY
                   11179:                histsave(line); 
                   11180: #else
                   11181:                histsave(source->line, line, 1); 
                   11182: #endif
                   11183:                histpush--; 
                   11184:        }
                   11185:        line[0] = '\0';
                   11186:        fclose(f);
                   11187: 
                   11188:        return 0;
                   11189: }
                   11190: 
                   11191: /******************************/
                   11192: /* Back up over last histsave */
                   11193: /******************************/
                   11194: void
                   11195: histbackup()
                   11196: {
                   11197:        static int last_line = -1;
                   11198: 
                   11199:        if (histptr > history && last_line != source->line) { 
                   11200:                source->line--;
                   11201:                afree((void*)*histptr, APERM);
                   11202:                histptr--;
                   11203:                last_line = source->line;
                   11204:        }
                   11205: }
                   11206: 
                   11207: /*
                   11208:  * get pointer to history given pattern
                   11209:  * pattern is a number or string
                   11210:  */
                   11211: char **
                   11212: histget(str)
                   11213:        char *str;
                   11214: {
                   11215:        register char **hp = NULL;
                   11216: 
                   11217:        if (*str == '-')
                   11218:                hp = histptr + getn(str);
                   11219:        else
                   11220:        if (digit(*str))
                   11221:                hp = histptr + (getn(str) - source->line);
                   11222:        else 
                   11223:        if (*str == '?') {      /* unanchored match */
                   11224:                for (hp = histptr-1; hp >= history; hp--)
                   11225:                        if (strstr(*hp, str+1) != NULL)
                   11226:                                break;
                   11227:        } else {                /* anchored match */
                   11228:                for (hp = histptr; hp >= history; hp--)
                   11229:                        if (strncmp(*hp, str, strlen(str)) == 0)
                   11230:                                break;
                   11231:        }
                   11232: 
                   11233:        return (history <= hp && hp <= histptr) ? hp : NULL;
                   11234: }
                   11235: 
                   11236: char *
                   11237: histrpl(s, pat, rep, global)
                   11238:        char *s;
                   11239:        char *pat, *rep;
                   11240:        int global;
                   11241: {
                   11242:        char *s1, *p, *last = NULL;
                   11243:        int len = strlen(pat);
                   11244: 
                   11245:        if (strlen(s) - strlen(pat) + strlen(rep) >= LINE)
                   11246:                errorf("substitution too long\n");
                   11247:        line[0] = '\0';
                   11248:        p = line;
                   11249:        while (s1 = strstr(s, pat)) {
                   11250:                strncpy(p, s, s1 - s);          /* first part */
                   11251:                strcpy(p + (s1 - s), rep);      /* replacement */
                   11252:                s = s1 + len;
                   11253:                last = s1;
                   11254:                p = strchr(p, 0);
                   11255:                if (!global)
                   11256:                        s = "";
                   11257:        }
                   11258:        if (last)
                   11259:                strcpy(p, last + len);          /* last part */
                   11260:        else
                   11261:                errorf("substitution failed\n");
                   11262:        return line;
                   11263: }
                   11264: 
                   11265: /*
                   11266:  * Return the current position.
                   11267:  */
                   11268: char **
                   11269: histpos()
                   11270: {
                   11271:        return current;
                   11272: }
                   11273: 
                   11274: int
                   11275: histN()
                   11276: {
                   11277:        return curpos;
                   11278: }
                   11279: 
                   11280: int
                   11281: histnum(n)
                   11282: {
                   11283:        int     last = histptr - history;
                   11284: 
                   11285:        if (n < 0 || n >= last) {
                   11286:                current = histptr;
                   11287:                curpos = last;
                   11288:                return last;
                   11289:        }  else {
                   11290:                current = &history[n];
                   11291:                curpos = n;
                   11292:                return n;
                   11293:        }
                   11294: }
                   11295: 
                   11296: /*
                   11297:  * This will become unecessary if histget is modified to allow
                   11298:  * searching from positions other than the end, and in either 
                   11299:  * direction.
                   11300:  */
                   11301: char *
                   11302: findhist(start, fwd, str)
                   11303:        int     start;
                   11304:        int     fwd;
                   11305:        char    *str;
                   11306: {
                   11307:        int      pos = start;
                   11308:        char     *line, *last;
                   11309: 
                   11310:        /* XXX check that we are valid after this */
                   11311:        if (fwd)
                   11312:                pos++;
                   11313:        else
                   11314:                pos--;
                   11315:        histnum(pos);
                   11316:        line = *histpos();
                   11317:        do {
                   11318:                last = line;
                   11319:                if (strstr(line, str) != 0) {
                   11320:                        /* keep position current */
                   11321:                        return (line);
                   11322:                }
                   11323:                if (fwd)
                   11324:                        pos++;
                   11325:                else
                   11326:                        pos--;
                   11327:                histnum(pos);
                   11328:                line = *histpos();
                   11329:        } while (line && *line && line != last && pos>0);
                   11330: 
                   11331:        histnum(start);
                   11332:        if (pos <= 0)
                   11333:                return (char*)-1; /* TODO */
                   11334:        return NULL;
                   11335: }
                   11336: 
                   11337: #ifdef EASY_HISTORY
                   11338: /*
                   11339:  * save command in history
                   11340:  */
                   11341: void
                   11342: histsave(cmd)
                   11343:        char *cmd;
                   11344: {
                   11345:        register char **hp = histptr;
                   11346:        char *cp;
                   11347: 
                   11348:        if (++hp >= history + HISTORY) { /* remove oldest command */
                   11349:                afree((void*)*history, APERM);
                   11350:                for (hp = history; hp < history + HISTORY - 1; hp++)
                   11351:                        hp[0] = hp[1];
                   11352:        }
                   11353:        *hp = strsave(cmd, APERM);
                   11354:        if ((cp = strchr(*hp, '\n')) != NULL)
                   11355:                *cp = '\0';
                   11356:        histptr = hp;
                   11357: }
                   11358: 
                   11359: /*
                   11360:  * 92-04-25 <sjg@zen>
                   11361:  * A simple history file implementation.
                   11362:  * At present we only save the history when we exit.
                   11363:  * This can cause problems when there are multiple shells are 
                   11364:  * running under the same user-id.  The last shell to exit gets 
                   11365:  * to save its history.
                   11366:  */
                   11367: void
                   11368: hist_init(s)
                   11369:   Source *s;
                   11370: {
                   11371:   static int once = 0;
                   11372:   FILE *fh;
                   11373:   
                   11374:   if (once++)
                   11375:     return;
                   11376: 
                   11377:   if (fh = hist_open("r"))
                   11378:   {
                   11379:     while (fgets(line, sizeof(line), fh) != NULL)
                   11380:     {
                   11381:       histsave(line); 
                   11382:       s->line++;
                   11383:     }
                   11384:     line[0] = '\0';
                   11385:     fclose(fh);
                   11386: #if 0  /* this might be a good idea? */
                   11387:     hist_fh = hist_open("a");
                   11388: #endif
                   11389:   }
                   11390:   
                   11391: }
                   11392: 
                   11393: void
                   11394: init_histvec()
                   11395: {      ;       }
                   11396: 
                   11397: /*
                   11398:  * save our history.
                   11399:  * We check that we do not have more than we are allowed.
                   11400:  * If the history file is read-only we do nothing.
                   11401:  * Handy for having all shells start with a useful history set.
                   11402:  */
                   11403: 
                   11404: void
                   11405: hist_finish()
                   11406: {
                   11407:   static int once = 0;
                   11408:   FILE *fh;
                   11409:   register int i, mx;
                   11410:   register char **hp, *mode = "w";
                   11411:   
                   11412:   if (once++)
                   11413:     return;
                   11414:   if ((mx = atoi(strval(global("HISTSIZE")))) > HISTORY || mx <= 0)
                   11415:     mx = HISTORY;
                   11416:   /* check how many we have */
                   11417:   i = histptr - history;
                   11418:   if (i >= mx)
                   11419:   {
                   11420:     hp = &histptr[-mx];
                   11421:   }
                   11422:   else
                   11423:   {
                   11424:     hp = history;
                   11425:   }
                   11426:   if (fh = hist_open(mode))
                   11427:   {
                   11428:     for (i = 0; i < mx && hp[i]; i++)
                   11429:       fprintf(fh, "%s\n", hp[i]);
                   11430:     fclose(fh);
                   11431:   }
                   11432: }
                   11433: 
                   11434: 
                   11435: /*
                   11436:  * simply grab the nominated history file.
                   11437:  */
                   11438: static FILE *
                   11439: hist_open(mode)
                   11440:   char *mode;
                   11441: {
                   11442:   register char *rcp;
                   11443:   FILE *fh;
                   11444:   char name[128];
                   11445:   
                   11446:   if ((rcp = strval(global("HISTFILE"))) == NULL || *rcp == '\0')
                   11447:   {
                   11448:     (void) sprintf(name, "%s/%s", strval(global("HOME")), HISTFILE);
                   11449:     rcp = name;
                   11450:   }
                   11451:   return fopen(rcp, mode);
                   11452: }
                   11453: 
                   11454: #else /* EASY_HISTORY */
                   11455: 
                   11456: /*
                   11457:  *     Routines added by Peter Collinson BSDI(Europe)/Hillside Systems to
                   11458:  *     a) permit HISTSIZE to control number of lines of history stored
                   11459:  *     b) maintain a physical history file
                   11460:  *
                   11461:  *     It turns out that there is a lot of ghastly hackery here
                   11462:  */
                   11463: 
                   11464: 
                   11465: /*
                   11466:  * save command in history
                   11467:  */
                   11468: void
                   11469: histsave(lno, cmd, dowrite)
                   11470:        int lno;
                   11471:        char *cmd;
                   11472:        int dowrite;
                   11473: {
                   11474:        register char **hp;
                   11475:        char *cp;
                   11476: 
                   11477:        cmd = strsave(cmd, APERM);
                   11478:        if ((cp = strchr(cmd, '\n')) != NULL)
                   11479:                *cp = '\0';
                   11480: 
                   11481:        if (histfd && dowrite)
                   11482:                writehistfile(lno, cmd);
                   11483: 
                   11484:        hp = histptr;
                   11485:                
                   11486:        if (++hp >= history + histsize) { /* remove oldest command */
                   11487:                afree((void*)*history, APERM);
                   11488:                for (hp = history; hp < history + histsize - 1; hp++)
                   11489:                        hp[0] = hp[1];
                   11490:        }
                   11491:        *hp = cmd;
                   11492:        histptr = hp;
                   11493: }
                   11494: 
                   11495: /*
                   11496:  *     set history
                   11497:  *     this means reallocating the dataspace
                   11498:  */
                   11499: void
                   11500: sethistsize(n)
                   11501:        int n;
                   11502: {
                   11503:        int     offset;
                   11504:        
                   11505:        if (n != histsize) {
                   11506:                offset = histptr - history;
                   11507:                history = (char **)aresize(history, n*sizeof(char *), APERM);
                   11508: 
                   11509:                if (n < histsize && offset > histsize)
                   11510:                        offset = histsize;
                   11511: 
                   11512:                histsize = n;
                   11513:                histptr = history + offset;
                   11514:        }
                   11515: }
                   11516: 
                   11517: /*
                   11518:  *     set history file
                   11519:  *     This can mean reloading/resetting/starting history file
                   11520:  *     maintenance
                   11521:  */
                   11522: void
                   11523: sethistfile(name)
                   11524:        char *name;
                   11525: {
                   11526:        /* if not started then nothing to do */
                   11527:        if (hstarted == 0)
                   11528:                return;
                   11529: 
                   11530:        /* if the name is the same as the name we have */
                   11531:        if (hname && strcmp(hname, name) == 0)
                   11532:                return;
                   11533: 
                   11534:        /*
                   11535:         * its a new name - possibly
                   11536:         */
                   11537:        if (histfd) {
                   11538:                /* yes the file is open */
                   11539:                (void) close(histfd);
                   11540:                histfd = 0;
                   11541:                hsize = 0;
                   11542:                afree(hname, APERM);
                   11543:                hname = NULL;
                   11544:                /* let's reset the history */
                   11545:                histptr = history - 1;
                   11546:                source->line = 0;
                   11547:        }
                   11548: 
                   11549:        hist_init(source);
                   11550: }
                   11551: 
                   11552: /*
                   11553:  *     initialise the history vector
                   11554:  */
                   11555: void
                   11556: init_histvec()
                   11557: {
                   11558:        if (history == (char **)NULL) {
                   11559:                history = (char **)alloc(histsize*sizeof (char *), APERM);
                   11560:                histptr = history-1;
                   11561:        }
                   11562: }
                   11563:        
                   11564: /*
                   11565:  *     Write history data to a file nominated by HISTFILE
                   11566:  *     if HISTFILE is unset then history still happens, but
                   11567:  *     the data is not written to a file
                   11568:  *     All copies of ksh looking at the file will maintain the
                   11569:  *     same history. This is ksh behaviour.
                   11570:  *
                   11571:  *     This stuff uses mmap()
                   11572:  *     if your system ain't got it - then you'll have to undef HISTORYFILE
                   11573:  */
                   11574:        
                   11575: /*
                   11576:  *     Open a history file
                   11577:  *     Format is:
                   11578:  *     Bytes 1, 2: HMAGIC - just to check that we are dealing with
                   11579:  *                 the correct object
                   11580:  *     Then follows a number of stored commands
                   11581:  *     Each command is
                   11582:  *     <command byte><command number(4 bytes)><bytes><null>
                   11583:  */
                   11584: #define HMAGIC1                0xab
                   11585: #define HMAGIC2                0xcd
                   11586: #define COMMAND                0xff
                   11587: 
                   11588: void
                   11589: hist_init(s)
                   11590:        Source *s;
                   11591: {
                   11592:        unsigned char   *base;
                   11593:        int     lines;
                   11594:        int     bytes;
                   11595:        
                   11596:        hstarted = 1;
                   11597:        
                   11598:        if (flag[FTALKING] == 0)
                   11599:                return;
                   11600: 
                   11601:        hname = strval(global("HISTFILE"));
                   11602:        if (hname == NULL)
                   11603:                return;
                   11604:        hname = strsave(hname, APERM);
                   11605: 
                   11606:   retry:
                   11607:        /* we have a file and are interactive */
                   11608:        if ((histfd = open(hname, O_RDWR|O_CREAT|O_APPEND, 0600)) < 0)
                   11609:                return;
                   11610: 
                   11611:        histfd = fcntl(histfd, F_DUPFD, FDBASE);
                   11612:        
                   11613:        (void) fcntl(histfd, F_SETFD, 1); /* close on exec */
                   11614:        
                   11615:        (void) flock(histfd, LOCK_EX);
                   11616: 
                   11617:        hsize = lseek(histfd, 0L, L_XTND);
                   11618: 
                   11619:        if (hsize == 0) {
                   11620:                /* add magic */
                   11621:                if (sprinkle(histfd)) {
                   11622:                        hist_finish();
                   11623:                        return;
                   11624:                }
                   11625:        }
                   11626:        else if (hsize > 0) {
                   11627:                /*
                   11628:                 * we have some data
                   11629:                 */
                   11630:                base = (unsigned char *)mmap(0, hsize, PROT_READ, MAP_FLAGS, histfd, 0);
                   11631:                /*
                   11632:                 * check on its validity
                   11633:                 */
                   11634:                if ((int)base == -1 || *base != HMAGIC1 || base[1] != HMAGIC2) {
                   11635:                        if ((int)base !=  -1)
                   11636:                                munmap((caddr_t)base, hsize);
                   11637:                        hist_finish();
                   11638:                        unlink(hname);
                   11639:                        goto retry;
                   11640:                }
                   11641:                if (hsize > 2) {
                   11642:                        lines = hist_count_lines(base+2, hsize-2);
                   11643:                        if (lines > histsize) {
                   11644:                                /* we need to make the file smaller */
                   11645:                                if (hist_shrink(base, hsize))
                   11646:                                        unlink(hname);
                   11647:                                munmap((caddr_t)base, hsize);
                   11648:                                hist_finish();
                   11649:                                goto retry;
                   11650:                        }
                   11651:                }
                   11652:                histload(s, base+2, hsize-2);
                   11653:                munmap((caddr_t)base, hsize);
                   11654:        }
                   11655:        (void) flock(histfd, LOCK_UN);
                   11656:        hsize = lseek(histfd, 0L, L_XTND);
                   11657: }
                   11658: 
                   11659: typedef enum state {
                   11660:        shdr,           /* expecting a header */
                   11661:        sline,          /* looking for a null byte to end the line */
                   11662:        sn1,            /* bytes 1 to 4 of a line no */
                   11663:        sn2, sn3, sn4,
                   11664: } State;
                   11665: 
                   11666: static int
                   11667: hist_count_lines(base, bytes)
                   11668:        register unsigned char *base;
                   11669:        register int bytes;
                   11670: {
                   11671:        State state = shdr;
                   11672:        register lines = 0;
                   11673:        
                   11674:        while (bytes--) {
                   11675:                switch (state)
                   11676:                {
                   11677:                case shdr:
                   11678:                        if (*base == COMMAND)
                   11679:                                state = sn1;
                   11680:                        break;
                   11681:                case sn1:
                   11682:                        state = sn2; break;
                   11683:                case sn2:
                   11684:                        state = sn3; break;
                   11685:                case sn3:
                   11686:                        state = sn4; break;
                   11687:                case sn4:
                   11688:                        state = sline; break;
                   11689:                case sline:
                   11690:                        if (*base == '\0')
                   11691:                                lines++, state = shdr;
                   11692:                }
                   11693:                base++;
                   11694:        }
                   11695:        return lines;
                   11696: }
                   11697: 
                   11698: /*
                   11699:  *     Shrink the history file to histsize lines
                   11700:  */
                   11701: static int
                   11702: hist_shrink(oldbase, oldbytes)
                   11703:        unsigned char *oldbase;
                   11704:        int oldbytes;
                   11705: {
                   11706:        int fd;
                   11707:        char    nfile[1024];
                   11708:        struct  stat statb;
                   11709:        unsigned char *nbase = oldbase;
                   11710:        int nbytes = oldbytes;
                   11711: 
                   11712:        nbase = hist_skip_back(nbase, &nbytes, histsize);
                   11713:        if (nbase == NULL)
                   11714:                return 1;
                   11715:        if (nbase == oldbase)
                   11716:                return 0;
                   11717:        
                   11718:        /*
                   11719:         *      create temp file
                   11720:         */
                   11721:        (void) sprintf(nfile, "%s.%d", hname, getpid());
                   11722:        if ((fd = creat(nfile, 0600)) < 0)
                   11723:                return 1;
                   11724: 
                   11725:        if (sprinkle(fd)) {
                   11726:                close(fd);
                   11727:                unlink(nfile);
                   11728:                return 1;
                   11729:        }
                   11730:        if (write(fd, nbase, nbytes) != nbytes) {
                   11731:                close(fd);
                   11732:                unlink(nfile);
                   11733:                return 1;
                   11734:        }
                   11735:        /*
                   11736:         *      worry about who owns this file
                   11737:         */
                   11738:        if (fstat(histfd, &statb) >= 0)
                   11739:                fchown(fd, statb.st_uid, statb.st_gid);
                   11740:        close(fd);
                   11741:        
                   11742:        /*
                   11743:         *      rename
                   11744:         */
                   11745:        if (rename(nfile, hname) < 0)
                   11746:                return 1;
                   11747:        return 0;
                   11748: }
                   11749:        
                   11750: 
                   11751: /*
                   11752:  *     find a pointer to the data `no' back from the end of the file
                   11753:  *     return the pointer and the number of bytes left
                   11754:  */
                   11755: static unsigned char *
                   11756: hist_skip_back(base, bytes, no)
                   11757:        unsigned char *base;
                   11758:        int *bytes;
                   11759:        int no;
                   11760: {
                   11761:        register int lines = 0;
                   11762:        register unsigned char *ep;
                   11763: 
                   11764:        
                   11765: 
                   11766:        for (ep = base + *bytes; ep > base; ep--)
                   11767:        {
                   11768:                while (*ep != COMMAND) {
                   11769:                        if (--ep == base)
                   11770:                                break;
                   11771:                }
                   11772:                if (++lines == no) {
                   11773:                        *bytes = *bytes - ((char *)ep - (char *)base);
                   11774:                        return ep;
                   11775:                }
                   11776:        }
                   11777:        if (ep > base)
                   11778:                return base;
                   11779:        return NULL;
                   11780: }
                   11781: 
                   11782: /*
                   11783:  *     load the history structure from the stored data
                   11784:  */
                   11785: static void
                   11786: histload(s, base, bytes)
                   11787:        Source *s;
                   11788:        register unsigned char *base;
                   11789:        register int bytes;
                   11790: {
                   11791:        State state;
                   11792:        int     lno;
                   11793:        unsigned char   *line;
                   11794:        
                   11795:        for (state = shdr; bytes-- > 0; base++) {
                   11796:                switch (state) {
                   11797:                case shdr:
                   11798:                        if (*base == COMMAND)
                   11799:                                state = sn1;
                   11800:                        break;
                   11801:                case sn1:
                   11802:                        lno = (((*base)&0xff)<<24);
                   11803:                        state = sn2;
                   11804:                        break;
                   11805:                case sn2:
                   11806:                        lno |= (((*base)&0xff)<<16);
                   11807:                        state = sn3;
                   11808:                        break;
                   11809:                case sn3:
                   11810:                        lno |= (((*base)&0xff)<<8);
                   11811:                        state = sn4;
                   11812:                        break;
                   11813:                case sn4:
                   11814:                        lno |= (*base)&0xff;
                   11815:                        line = base+1;
                   11816:                        state = sline;
                   11817:                        break;
                   11818:                case sline:
                   11819:                        if (*base == '\0') {
                   11820:                                /* worry about line numbers */
                   11821:                                if (histptr >= history && lno-1 != s->line) {
                   11822:                                        /* a replacement ? */
                   11823:                                        histinsert(s, lno, line);
                   11824:                                }
                   11825:                                else {
                   11826:                                        s->line = lno;
                   11827:                                        histsave(lno, (char *)line, 0);
                   11828:                                }
                   11829:                                state = shdr;
                   11830:                        }
                   11831:                }
                   11832:        }
                   11833: }
                   11834:                                
                   11835: /*
                   11836:  *     Insert a line into the history at a specified number
                   11837:  */
                   11838: static void
                   11839: histinsert(s, lno, line)
                   11840:        Source *s;
                   11841:        int lno;
                   11842:        unsigned char *line;
                   11843: {
                   11844:        register char **hp;
                   11845:        
                   11846:        if (lno >= s->line-(histptr-history) && lno <= s->line) {
                   11847:                hp = &histptr[lno-s->line];
                   11848:                if (*hp)
                   11849:                        afree((void*)*hp, APERM);
                   11850:                *hp = strsave((char *)line, APERM);
                   11851:        }
                   11852: }
                   11853: 
                   11854: /*
                   11855:  *     write a command to the end of the history file
                   11856:  *     This *MAY* seem easy but it's also necessary to check
                   11857:  *     that the history file has not changed in size.
                   11858:  *     If it has - then some other shell has written to it
                   11859:  *     and we should read those commands to update our history
                   11860:  */
                   11861: static void
                   11862: writehistfile(lno, cmd)
                   11863:        int lno;
                   11864:        char *cmd;
                   11865: {
                   11866:        int     sizenow;
                   11867:        unsigned char   *base;
                   11868:        unsigned char   *new;
                   11869:        int     bytes;
                   11870:        char    hdr[5];
                   11871:        
                   11872:        (void) flock(histfd, LOCK_EX);
                   11873:        sizenow = lseek(histfd, 0L, L_XTND);
                   11874:        if (sizenow != hsize) {
                   11875:                /*
                   11876:                 *      Things have changed
                   11877:                 */
                   11878:                if (sizenow > hsize) {
                   11879:                        /* someone has added some lines */
                   11880:                        bytes = sizenow - hsize;
                   11881:                        base = (unsigned char *)mmap(0, sizenow, PROT_READ, MAP_FLAGS, histfd, 0);
                   11882:                        if ((int)base == -1)
                   11883:                                goto bad;
                   11884:                        new = base + hsize;
                   11885:                        if (*new != COMMAND) {
                   11886:                                munmap((caddr_t)base, sizenow);
                   11887:                                goto bad;
                   11888:                        }
                   11889:                        source->line--;
                   11890:                        histload(source, new, bytes);
                   11891:                        source->line++;
                   11892:                        lno = source->line;
                   11893:                        munmap((caddr_t)base, sizenow);
                   11894:                        hsize = sizenow;
                   11895:                } else {
                   11896:                        /* it has shrunk */
                   11897:                        /* but to what? */
                   11898:                        /* we'll give up for now */
                   11899:                        goto bad;
                   11900:                }
                   11901:        }
                   11902:        /*
                   11903:         *      we can write our bit now
                   11904:         */
                   11905:        hdr[0] = COMMAND;
                   11906:        hdr[1] = (lno>>24)&0xff;
                   11907:        hdr[2] = (lno>>16)&0xff;
                   11908:        hdr[3] = (lno>>8)&0xff;
                   11909:        hdr[4] = lno&0xff;
                   11910:        (void) write(histfd, hdr, 5);
                   11911:        (void) write(histfd, cmd, strlen(cmd)+1);
                   11912:        hsize = lseek(histfd, 0L, L_XTND);
                   11913:        (void) flock(histfd, LOCK_UN);
                   11914:        return;
                   11915: bad:
                   11916:        hist_finish();
                   11917: }
                   11918: 
                   11919: void
                   11920: hist_finish()
                   11921: {
                   11922:        (void) flock(histfd, LOCK_UN);
                   11923:        (void) close(histfd);
                   11924:        histfd = 0;
                   11925: }
                   11926: 
                   11927: /*
                   11928:  *     add magic to the history file
                   11929:  */
                   11930: static int
                   11931: sprinkle(fd)
                   11932:        int fd;
                   11933: {
                   11934:        static char mag[] = { HMAGIC1, HMAGIC2 };
                   11935: 
                   11936:        return(write(fd, mag, 2) != 2);
                   11937: }
                   11938: 
                   11939: #endif
                   11940: ./pdksh/sh/main.c   644    653   1762       23020  5302634017  11120 0ustar  hlu/*
                   11941:  * startup, main loop, enviroments and error handling
                   11942:  */
                   11943: 
                   11944: #ifndef lint
                   11945: static char *RCSid = "$Id: main.c,v 1.6 1992/08/12 14:15:39 sjg Exp $";
                   11946: #endif
                   11947: 
                   11948: #define        EXTERN                          /* define EXTERNs in sh.h */
                   11949: 
                   11950: #include "stdh.h"
                   11951: #include <unistd.h>
                   11952: #include <fcntl.h>
                   11953: #include <signal.h>
                   11954: #include <errno.h>
                   11955: #include <setjmp.h>
                   11956: #include <time.h>
                   11957: #include "sh.h"
                   11958: 
                   11959: #if !defined(HAVE_REMOVE) && !defined(remove)
                   11960: #define remove(x)      unlink(x)
                   11961: #endif
                   11962: 
                   11963: /*
                   11964:  * global data
                   11965:  */
                   11966: 
                   11967: Area   aperm;
                   11968: 
                   11969: static void    reclaim ARGS((void));
                   11970: 
                   11971: /*
                   11972:  * shell initialization
                   11973:  */
                   11974: 
                   11975: static char    initifs [] = "IFS= \t\n"; /* must be R/W */
                   11976: 
                   11977: static const   char   initsubs [] = 
                   11978: #ifdef sun                             /* sun's don't have a real /bin */
                   11979:   "${SHELL:=/bin/sh} ${PATH:=/usr/bin:/usr/ucb:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${PS3:=#? } ${MAILCHECK:=600}";
                   11980: #else
                   11981:   "${SHELL:=/bin/sh} ${PATH:=/bin:/usr/bin:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${PS3:=#? } ${MAILCHECK:=600}";
                   11982: #endif
                   11983: 
                   11984: static const   char *initcoms [] = {
                   11985:        "cd", ".", NULL,                /* set up $PWD */
                   11986:        "typeset", "-x", "SHELL", "PATH", "HOME", NULL,
                   11987:        "typeset", "-r", "PWD", "OLDPWD", NULL,
                   11988:        "typeset", "-i", "SECONDS=0", "OPTIND=1", NULL,
                   11989:        "alias",
                   11990:          "integer=typeset -i", "pwd=print -r \"$PWD\"",
                   11991:          "history=fc -l", "r=fc -e -", "nohup=nohup ",
                   11992:          "login=exec login", "newgrp=exec newgrp",
                   11993:          "type=whence -v", "functions=typeset -f",
                   11994:          "echo=print", "true=:", "false=let", "[=\\[",
                   11995: #ifdef JOBS
                   11996:          "suspend=kill -STOP $$",
                   11997: #endif
                   11998:          NULL,
                   11999: 
                   12000:        
                   12001:        NULL
                   12002: };
                   12003: 
                   12004: #ifdef USE_TRACE
                   12005: /*
                   12006:  * use SIGUSR1 to bump up Trace_level
                   12007:  * use SIGUSR2 to clear Trace_level
                   12008:  */
                   12009: void
                   12010: set_TraceLev(sig)
                   12011:   int sig;
                   12012: {
                   12013:   switch(sig)
                   12014:   {
                   12015:   case SIGUSR1:
                   12016:     Trace_level++;
                   12017:     break;
                   12018:   case SIGUSR2:
                   12019:     Trace_level = 0;
                   12020:     break;
                   12021:   }
                   12022: #if defined(_SYSV) && !defined(USE_SIGACT)
                   12023:   if (sig > 0)
                   12024:     (void) signal(sig, set_TraceLev);
                   12025: #endif
                   12026:   return;
                   12027: }
                   12028: #endif
                   12029: 
                   12030: main(argc, argv, envp)
                   12031:        int argc;
                   12032:        register char **argv;
                   12033:        char **envp;
                   12034: {
                   12035:        register int i;
                   12036:        register char *arg;
                   12037:        int cflag = 0, qflag = 0, fflag = 0;
                   12038:        int argi;
                   12039:        char *name;
                   12040:        register Source *s;
                   12041:        register struct block *l = &globals;
                   12042:        register char **wp0, **wp;
                   12043:        extern char ksh_version [];
                   12044:        extern time_t time();
                   12045: 
                   12046: #ifdef USE_SIGACT
                   12047:        sigemptyset(&Sigact.sa_mask);
                   12048:        sigemptyset(&Sigact_dfl.sa_mask);
                   12049:        sigemptyset(&Sigact_ign.sa_mask);
                   12050:        sigemptyset(&Sigact_trap.sa_mask);
                   12051:        Sigact.sa_flags = 0;
                   12052:        Sigact_dfl.sa_flags = 0;
                   12053:        Sigact_ign.sa_flags = 0;
                   12054:        Sigact_trap.sa_flags = 0;
                   12055:        Sigact_dfl.sa_handler = SIG_DFL;
                   12056:        Sigact_ign.sa_handler = SIG_IGN;
                   12057:        Sigact_trap.sa_handler = trapsig;
                   12058: #endif
                   12059:        ainit(&aperm);          /* initialize permanent Area */
                   12060: 
                   12061: #ifndef F_SETFD
                   12062:   init_clexec();
                   12063: #endif
                   12064:        /* set up base enviroment */
                   12065:        e.type = E_NONE;
                   12066:        ainit(&e.area);
                   12067:        e.loc = l;
                   12068:        e.savefd = NULL;
                   12069:        e.oenv = NULL;
                   12070: 
                   12071:        initctypes();
                   12072: 
                   12073:        /* open file streams for fd's 0,1,2 */
                   12074:        fopenshf(0);    fopenshf(1);    fopenshf(2);
                   12075: 
                   12076:        /* set up variable and command dictionaries */
                   12077:        newblock();             /* set up global l->vars and l->funs */
                   12078:        tinit(&commands, APERM);
                   12079:        tinit(&builtins, APERM);
                   12080:        tinit(&lexicals, APERM);
                   12081:        tinit(&homedirs, APERM);
                   12082: 
                   12083:        init_histvec();
                   12084:        
                   12085:        /* import enviroment */
                   12086:        if (envp != NULL)
                   12087:                for (wp = envp; *wp != NULL; wp++)
                   12088:                        import(*wp);
                   12089: 
                   12090:        kshpid = getpid();
                   12091:        typeset(initifs, 0, 0); /* for security */
                   12092:        typeset(ksh_version, 0, 0); /* RDONLY */
                   12093: 
                   12094: #ifdef USE_TRACE
                   12095: #ifdef USE_SIGACT
                   12096:        Sigact.sa_handler = set_TraceLev;
                   12097:        sigaction(SIGUSR1, &Sigact, NULL);
                   12098:        sigaction(SIGUSR2, &Sigact, NULL);
                   12099: #else
                   12100:        (void) signal(SIGUSR1, set_TraceLev);
                   12101:        (void) signal(SIGUSR2, set_TraceLev);
                   12102: #endif
                   12103:        _TRACE(0, ("Traces enabled.")); /* allow _TRACE to setup */
                   12104: #endif
                   12105: 
                   12106:        /* define shell keywords */
                   12107:        keywords();
                   12108: 
                   12109:        /* define built-in commands */
                   12110:        for (i = 0; shbuiltins[i].name != NULL; i++)
                   12111:                builtin(shbuiltins[i].name, shbuiltins[i].func);
                   12112:        for (i = 0; kshbuiltins[i].name != NULL; i++)
                   12113:                builtin(kshbuiltins[i].name, kshbuiltins[i].func);
                   12114: 
                   12115:        /* assign default shell variable values */
                   12116:        substitute(initsubs, 0);
                   12117:        setint(typeset("PPID", INTEGER, 0), (long) getppid());
                   12118:        typeset("PPID", RDONLY, 0);
                   12119:        setint(typeset("RANDOM", INTEGER, 0), (long) time((time_t *)0));
                   12120:        /* execute initialization statements */
                   12121:        for (wp0 = (char**) initcoms; *wp0 != NULL; wp0 = wp+1) {
                   12122:                /* copy because the alias initializers are readonly */
                   12123:                for (wp = wp0; *wp != NULL; wp++)
                   12124:                        *wp = strsave(*wp, ATEMP);
                   12125:                shcomexec(wp0);
                   12126:        }
                   12127:        afreeall(ATEMP);
                   12128: 
                   12129:        if (geteuid() == 0)
                   12130:                setstr(global("PS1"), "# ");
                   12131: 
                   12132:        s = pushs(SFILE);
                   12133:        s->u.file = stdin;
                   12134:        cflag = 0;
                   12135:        name = *argv;
                   12136: 
                   12137:        /* what a bloody mess */
                   12138:        if ((argi = 1) < argc) {
                   12139:                if (argv[argi][0] == '-' && argv[argi][1] != '\0') {
                   12140:                        for (arg = argv[argi++]+1; *arg; arg++) {
                   12141:                                switch (*arg) {
                   12142:                                  case 'c':
                   12143:                                        cflag = 1;
                   12144:                                        if (argi < argc) {
                   12145:                                                s->type = SSTRING;
                   12146:                                                s->str = argv[argi++];
                   12147:                                        }
                   12148:                                        break;
                   12149:        
                   12150:                                  case 'q':
                   12151:                                        qflag = 1;
                   12152:                                        break;
                   12153: 
                   12154:                                  default:
                   12155:                                        if (*arg>='a' && *arg<='z')
                   12156:                                                flag[FLAG(*arg)]++;
                   12157:                                }
                   12158:                        }
                   12159:                }
                   12160:                if (s->type == SFILE && argi < argc && !flag[FSTDIN]) {
                   12161:                        s->file = name = argv[argi++];
                   12162:                        if ((s->u.file = fopen(name, "r")) == NULL)
                   12163:                                errorf("%s: cannot open\n", name);
                   12164:                        fflag = 1;
                   12165: #ifdef linux
                   12166:                        setfileno (s->u.file, savefd(fileno(s->u.file)));
                   12167: #else
                   12168:                        fileno(s->u.file) = savefd(fileno(s->u.file));
                   12169: #endif
                   12170:                        setvbuf(s->u.file, (char *)NULL, _IOFBF, BUFSIZ);
                   12171:                }
                   12172:        }
                   12173: 
                   12174:        if (s->type == SFILE) {
                   12175:                if (fileno(s->u.file) == 0)
                   12176:                        flag[FSTDIN] = 1;
                   12177:                if (isatty(0) && isatty(1) && !cflag && !fflag)
                   12178:                        flag[FTALKING] = 1;
                   12179:                if (flag[FTALKING] && flag[FSTDIN])
                   12180:                        s->type = STTY;
                   12181:        }
                   12182:        if (s->type == STTY) {
                   12183:                ttyfd = fcntl(0, F_DUPFD, FDBASE);
                   12184: #ifdef F_SETFD
                   12185:                (void) fcntl(ttyfd, F_SETFD, 1);
                   12186: #else
                   12187:                (void) fd_clexec(ttyfd);
                   12188: #endif
                   12189: #ifdef EMACS
                   12190:                x_init_emacs();
                   12191: #endif
                   12192:        }
                   12193: 
                   12194:        /* initialize job control */
                   12195:        j_init();
                   12196: 
                   12197:        if (!qflag)
                   12198:                ignoresig(SIGQUIT);
                   12199: 
                   12200:        l->argv = &argv[argi];
                   12201:        l->argc = argc - argi;
                   12202:        l->argv[0] = name;
                   12203:        resetopts();
                   12204: 
                   12205:        if (name[0] == '-') {
                   12206:                flag[FTALKING] = 1;
                   12207:                (void) include("/etc/profile");
                   12208:                (void) include(".profile");
                   12209:        }
                   12210: 
                   12211:        /* include $ENV */
                   12212:        arg = substitute(strval(global("ENV")), DOTILDE);
                   12213:        if (*arg != '\0')
                   12214:                (void) include(arg);
                   12215: 
                   12216:        if (flag[FTALKING])
                   12217:        {
                   12218: #ifdef USE_SIGACT
                   12219:          sigaction(SIGTERM, &Sigact_trap, NULL);
                   12220: #else
                   12221:          signal(SIGTERM, trapsig);
                   12222: #endif
                   12223:          ignoresig(SIGINT);
                   12224: #if defined(EMACS) || defined(VI)
                   12225:          init_editmode();
                   12226: #endif
                   12227:        } else
                   12228:          flag[FHASHALL] = 1;
                   12229: 
                   12230: #ifdef JOBS                    /* todo: could go before includes? */
                   12231:        if (s->type == STTY) {
                   12232:                flag[FMONITOR] = 1;
                   12233:                j_change();
                   12234:        }
                   12235: #endif
                   12236:        if (flag[FTALKING])
                   12237:        {
                   12238:          hist_init(s);
                   12239:        }
                   12240:        argc = shell(s);
                   12241:        leave(argc);
                   12242:        return 0;
                   12243: }
                   12244: 
                   12245: int
                   12246: include(name)
                   12247:        register char *name;
                   12248: {
                   12249:        register FILE *f;
                   12250:        register Source *s;
                   12251: 
                   12252:        if (strcmp(name, "-") != 0) {
                   12253:                f = fopen(name, "r");
                   12254:                if (f == NULL)
                   12255:                        return 0;
                   12256:                /* todo: the savefd doesn't get popped */
                   12257: #ifdef linux
                   12258:                setfileno (f, savefd(fileno(f))); /* questionable */
                   12259: #else
                   12260:                fileno(f) = savefd(fileno(f)); /* questionable */
                   12261: #endif
                   12262:                setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
                   12263:        } else
                   12264:                f = stdin;
                   12265:        s = pushs(SFILE);
                   12266:        s->u.file = f;
                   12267:        s->file = name;
                   12268:        /*return*/ shell(s);
                   12269:        if (f != stdin)
                   12270:                fclose(f);
                   12271:        return 1;
                   12272: }
                   12273: 
                   12274: int
                   12275: command(comm)
                   12276:        register char *comm;
                   12277: {
                   12278:        register Source *s;
                   12279: 
                   12280:        s = pushs(SSTRING);
                   12281:        s->str = comm;
                   12282:        return shell(s);
                   12283: }
                   12284: 
                   12285: /*
                   12286:  * run the commands from the input source, returning status.
                   12287:  */
                   12288: int
                   12289: shell(s)
                   12290:        Source *s;              /* input source */
                   12291: {
                   12292:        struct op *t;
                   12293:        volatile int attempts = 13;
                   12294:        volatile int wastty;
                   12295:        volatile int reading = 0;
                   12296:        extern void mcheck();
                   12297: 
                   12298:        newenv(E_PARSE);
                   12299:        e.interactive = 1;
                   12300:        exstat = 0;
                   12301:        if (setjmp(e.jbuf)) {
                   12302:                /*shellf("<unwind>");*/
                   12303:                if (trap)       /* pending SIGINT */
                   12304:                        shellf("\n");
                   12305:                if (reading && s->type == STTY && s->line)
                   12306:                        s->line--;
                   12307:                sigtraps[SIGINT].set = 0;
                   12308:        }
                   12309: 
                   12310:        while (1) {
                   12311:                if (trap)
                   12312:                        runtraps();
                   12313:                if (flag[FTALKING])
                   12314:                {
                   12315: #ifdef USE_SIGACT
                   12316:                  sigaction(SIGINT, &Sigact_trap, NULL);
                   12317: #else
                   12318:                  signal(SIGINT, trapsig);
                   12319: #endif
                   12320:                }
                   12321: 
                   12322:                if (s->next == NULL)
                   12323:                        s->echo = flag[FVERBOSE];
                   12324: 
                   12325:                j_notify();
                   12326: 
                   12327:                if ((wastty = (s->type == STTY)) || s->type == SHIST) {
                   12328:                        prompt = substitute(strval(global("PS1")), 0);
                   12329:                        mcheck();
                   12330:                }
                   12331: 
                   12332:                reading = 1;
                   12333:                t = compile(s);
                   12334:                reading = 0;
                   12335:                j_reap();
                   12336:                if (t != NULL && t->type == TEOF)
                   12337:                        if (wastty && flag[FIGNEOF] && --attempts > 0) {
                   12338:                                shellf("Use `exit'\n");
                   12339:                                s->type = STTY;
                   12340:                                continue;
                   12341:                        }
                   12342:                        else
                   12343:                                break;
                   12344:                flushshf(2);    /* flush -v output */
                   12345: 
                   12346:                if (!flag[FNOEXEC] || s->type == STTY)
                   12347:                        execute(t, 0);
                   12348: 
                   12349:                reclaim();
                   12350:        }
                   12351:        /* Error: */
                   12352:        quitenv();
                   12353:        return exstat;
                   12354: }
                   12355: 
                   12356: void
                   12357: leave(rv)
                   12358:        int rv;
                   12359: {
                   12360:        if (e.type == E_TCOM && e.oenv != NULL) /* exec'd command */
                   12361:                unwind();
                   12362:        runtrap(&sigtraps[0]);
                   12363:        if (flag[FTALKING])
                   12364:        {
                   12365:          hist_finish();
                   12366:        }
                   12367:        j_exit();
                   12368:        exit(rv);
                   12369:        /* NOTREACHED */
                   12370: }
                   12371: 
                   12372: error()
                   12373: {
                   12374:        if (flag[FERREXIT] || !flag[FTALKING])
                   12375:                leave(1);
                   12376:        unwind();
                   12377: }
                   12378: 
                   12379: /* return to closest error handler or shell(), exit if none found */
                   12380: unwind()
                   12381: {
                   12382:        while (1)
                   12383:                switch (e.type) {
                   12384:                  case E_NONE:
                   12385:                        leave(1);
                   12386:                        /* NOTREACHED */
                   12387:                  case E_PARSE:
                   12388:                        longjmp(e.jbuf, 1);
                   12389:                        /* NOTREACHED */
                   12390:                  case E_ERRH:
                   12391:                        longjmp(e.jbuf, 1);
                   12392:                        /* NOTREACHED */
                   12393:                  default:
                   12394:                        quitenv();
                   12395:                        break;
                   12396:                }
                   12397: }
                   12398: 
                   12399: newenv(type)
                   12400: {
                   12401:        register struct env *ep;
                   12402: 
                   12403:        ep = (struct env *) alloc(sizeof(*ep), ATEMP);
                   12404:        *ep = e;
                   12405:        ainit(&e.area);
                   12406:        e.type = type;
                   12407:        e.oenv = ep;
                   12408:        e.savefd = NULL;
                   12409:        e.temps = NULL;
                   12410: }
                   12411: 
                   12412: quitenv()
                   12413: {
                   12414:        register struct env *ep;
                   12415:        register int fd;
                   12416: 
                   12417:        if ((ep = e.oenv) == NULL)
                   12418:                exit(exstat);   /* exit child */
                   12419:        if (e.loc != ep->loc)
                   12420:                popblock();
                   12421:        if (e.savefd != NULL)
                   12422:                for (fd = 0; fd < NUFILE; fd++)
                   12423:                        restfd(fd, e.savefd[fd]);
                   12424:        reclaim();
                   12425:        e = *ep;
                   12426:        afree(ep, ATEMP);
                   12427: }
                   12428: 
                   12429: /* remove temp files and free ATEMP Area */
                   12430: static void
                   12431: reclaim()
                   12432: {
                   12433:        register struct temp *tp;
                   12434: 
                   12435:        for (tp = e.temps; tp != NULL; tp = tp->next)
                   12436:                remove(tp->name);
                   12437:        e.temps = NULL;
                   12438:        afreeall(&e.area);
                   12439: }
                   12440: 
                   12441: void
                   12442: aerror(ap, msg)
                   12443:        Area *ap;
                   12444:        const char *msg;
                   12445: {
                   12446:        errorf("alloc internal error: %s\n", msg);
                   12447: }
                   12448: 
                   12449: ./pdksh/sh/tree.c   644    653   1762       22721  5243743617  11155 0ustar  hlu/*
                   12450:  * command tree climbing
                   12451:  */
                   12452: 
                   12453: #ifndef lint
                   12454: static char *RCSid = "$Id: tree.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   12455: #endif
                   12456: 
                   12457: #include "stdh.h"
                   12458: #include <errno.h>
                   12459: #include <setjmp.h>
                   12460: 
                   12461: #ifdef __STDC__
                   12462: # include <stdarg.h>
                   12463: #else
                   12464: # include <varargs.h>
                   12465: #endif
                   12466: #include "sh.h"
                   12467: 
                   12468: #define        FSTRING (FILE*)NULL
                   12469: 
                   12470: static int      tputc       ARGS((int c, FILE *f));
                   12471: static void     tputC       ARGS((int c, FILE *f));
                   12472: static void     tputS       ARGS((char *wp, FILE *f));
                   12473: static struct ioword **iocopy ARGS((struct ioword **iow, Area *ap));
                   12474: static void     iofree      ARGS((struct ioword **iow, Area *ap));
                   12475: 
                   12476: /*
                   12477:  * print a command tree
                   12478:  */
                   12479: 
                   12480: void
                   12481: ptree(t, f)
                   12482:        register struct op *t;
                   12483:        register FILE *f;
                   12484: {
                   12485:        register char **w;
                   12486:        struct ioword **ioact;
                   12487:        struct op *t1;
                   12488: 
                   12489:  Chain:
                   12490:        if (t == NULL)
                   12491:                return;
                   12492:        switch (t->type) {
                   12493:          case TCOM:
                   12494:                for (w = t->vars; *w != NULL; )
                   12495:                        fptreef(f, "%S ", *w++);
                   12496:                for (w = t->args; *w != NULL; )
                   12497:                        fptreef(f, "%S ", *w++);
                   12498:                break;
                   12499:          case TEXEC:
                   12500:                t = t->left;
                   12501:                goto Chain;
                   12502:          case TPAREN:
                   12503:                fptreef(f, "(%T)", t->left);
                   12504:                break;
                   12505:          case TPIPE:
                   12506:                fptreef(f, "%T| ", t->left);
                   12507:                t = t->right;
                   12508:                goto Chain;
                   12509:          case TLIST:
                   12510:                fptreef(f, "%T", t->left);
                   12511:                fptreef(f, "%;");
                   12512:                t = t->right;
                   12513:                goto Chain;
                   12514:          case TOR:
                   12515:          case TAND:
                   12516:                fptreef(f, "%T", t->left);
                   12517:                fptreef(f, "%s %T", (t->type==TOR) ? "||" : "&&", t->right);
                   12518:                break;
                   12519:          case TFOR:
                   12520:                fptreef(f, "for %s ", t->str);
                   12521:                if (t->vars != NULL) {
                   12522:                        fptreef(f, "in ");
                   12523:                        for (w = t->vars; *w; )
                   12524:                                fptreef(f, "%S ", *w++);
                   12525:                        fptreef(f, "%;");
                   12526:                }
                   12527:                fptreef(f, "do %T", t->left);
                   12528:                fptreef(f, "%;done ");
                   12529:                break;
                   12530:          case TCASE:
                   12531:                fptreef(f, "case %S in%;", t->str);
                   12532:                for (t1 = t->left; t1 != NULL; t1 = t1->right) {
                   12533:                        fptreef(f, "(");
                   12534:                        for (w = t1->vars; *w != NULL; w++) {
                   12535:                                fptreef(f, "%S", *w);
                   12536:                                fptreef(f, "%c", (w[1] != NULL) ? '|' : ')');
                   12537:                        }
                   12538:                        fptreef(f, " %T;;%;", t1->left);
                   12539:                }
                   12540:                fptreef(f, "esac ");
                   12541:                break;
                   12542:          case TIF:
                   12543:                fptreef(f, "if %T", t->left);
                   12544:                fptreef(f, "%;");
                   12545:                t = t->right;
                   12546:                if (t->left != NULL) {
                   12547:                        fptreef(f, "then %T", t->left);
                   12548:                        fptreef(f, "%;");
                   12549:                }
                   12550:                if (t->right != NULL) {
                   12551:                        fptreef(f, "else %T", t->right);
                   12552:                        fptreef(f, "%;");
                   12553:                }
                   12554:                fptreef(f, "fi ");
                   12555:                break;
                   12556:          case TWHILE:
                   12557:          case TUNTIL:
                   12558:                fptreef(f, "%s %T",
                   12559:                        (t->type==TWHILE) ? "while" : "until",
                   12560:                        t->left);
                   12561:                fptreef(f, "%;do %T", t->right);
                   12562:                fptreef(f, "%;done ");
                   12563:                break;
                   12564:          case TBRACE:
                   12565:                fptreef(f, "{%;%T", t->left);
                   12566:                fptreef(f, "%;} ");
                   12567:                break;
                   12568:          case TASYNC:
                   12569:                fptreef(f, "%T&", t->left);
                   12570:                break;
                   12571:          case TFUNCT:
                   12572:                fptreef(f, "function %s %T", t->str, t->left);
                   12573:                break;
                   12574:          case TTIME:
                   12575:                fptreef(f, "time %T", t->left);
                   12576:                break;
                   12577:          default:
                   12578:                fptreef(f, "<botch>");
                   12579:                break;
                   12580:        }
                   12581:        if ((ioact = t->ioact) != NULL)
                   12582:                while (*ioact != NULL)
                   12583:                        pioact(f, *ioact++);
                   12584: }
                   12585: 
                   12586: pioact(f, iop)
                   12587:        register FILE *f;
                   12588:        register struct ioword *iop;
                   12589: {
                   12590:        register int flag = iop->flag;
                   12591:        if (iop->unit > 1)
                   12592:                fptreef(f, "%c", '0' + iop->unit );
                   12593: 
                   12594:        switch(flag&IOTYPE) {
                   12595:        case IOREAD:
                   12596:                fptreef(f, "< ");
                   12597:                break;
                   12598:        case IOHERE:
                   12599:                if (flag&IOSKIP)
                   12600:                        fptreef(f, "<<- ");
                   12601:                else
                   12602:                        fptreef(f, "<< ");
                   12603:                if (!(flag&IOEVAL))
                   12604:                        fptreef(f, "'");
                   12605:                break;
                   12606:        case IOCAT:
                   12607:                fptreef(f, ">> ");
                   12608:                break;
                   12609:        case IOWRITE:
                   12610:                if (flag&IOCLOB)
                   12611:                        fptreef(f, ">! ");
                   12612:                else
                   12613:                        fptreef(f, "> ");
                   12614:                break;
                   12615:        case IODUP:                     /* Needs help */
                   12616:                if (iop->unit == 0)
                   12617:                        fptreef(f, "<&");
                   12618:                else
                   12619:                        fptreef(f, ">&");
                   12620:                break;
                   12621:        }
                   12622: 
                   12623:        if ((flag&IOTYPE) == IOHERE) {
                   12624:                if (flag&IOEVAL)
                   12625:                        fptreef(f, "%s ", iop->name);
                   12626:                else
                   12627:                        fptreef(f, "%s' ", iop->name);
                   12628:        } else {
                   12629:                fptreef(f, "%S ", iop->name);
                   12630:        }
                   12631: }
                   12632: 
                   12633: 
                   12634: /*
                   12635:  * variants of fputc, fputs for ptreef and snptreef
                   12636:  */
                   12637: 
                   12638: static char   *snpf_s;         /* snptreef string */
                   12639: static int     snpf_n;         /* snptreef length */
                   12640: 
                   12641: static int
                   12642: tputc(c, f)
                   12643:        int c;
                   12644:        register FILE *f;
                   12645: {
                   12646:        if (f != NULL)
                   12647:                putc(c, f);
                   12648:        else
                   12649:                if (--snpf_n >= 0)
                   12650:                        *snpf_s++ = c;
                   12651:        return c;
                   12652: }
                   12653: 
                   12654: static void
                   12655: tputC(c, f)
                   12656:        register int c;
                   12657:        register FILE *f;
                   12658: {
                   12659:        if ((c&0x60) == 0) {            /* C0|C1 */
                   12660:                tputc((c&0x80) ? '$' : '^', f);
                   12661:                tputc(((c&0x7F)|0x40), f);
                   12662:        } else if ((c&0x7F) == 0x7F) {  /* DEL */
                   12663:                tputc((c&0x80) ? '$' : '^', f);
                   12664:                tputc('?', f);
                   12665:        } else
                   12666:                tputc(c, f);
                   12667: }
                   12668: 
                   12669: static void
                   12670: tputS(wp, f)
                   12671:        register char *wp;
                   12672:        register FILE *f;
                   12673: {
                   12674:        register int c, quoted=0;
                   12675: 
                   12676:        while (1)
                   12677:                switch ((c = *wp++)) {
                   12678:                  case EOS:
                   12679:                        return;
                   12680:                  case CHAR:
                   12681:                        tputC(*wp++, f);
                   12682:                        break;
                   12683:                  case QCHAR:
                   12684:                        if (!quoted)
                   12685:                                tputc('\\', f);
                   12686:                        tputC(*wp++, f);
                   12687:                        break;
                   12688:                  case OQUOTE:
                   12689:                        quoted = 1;
                   12690:                        tputc('"', f);
                   12691:                        break;
                   12692:                  case CQUOTE:
                   12693:                        quoted = 0;
                   12694:                        tputc('"', f);
                   12695:                        break;
                   12696:                  case OSUBST:
                   12697:                        tputc('$', f);
                   12698:                        tputc('{', f);
                   12699:                        while ((c = *wp++) != 0)
                   12700:                                tputc(c, f);
                   12701:                        if (*wp != CSUBST)
                   12702:                                tputC(*wp++, f);
                   12703:                        break;
                   12704:                  case CSUBST:
                   12705:                        tputc('}', f);
                   12706:                        break;
                   12707:                  case COMSUB:
                   12708:                        tputc('$', f);
                   12709:                        tputc('(', f);
                   12710:                        while (*wp != 0)
                   12711:                                tputC(*wp++, f);
                   12712:                        tputc(')', f);
                   12713:                        break;
                   12714:                }
                   12715: }
                   12716: 
                   12717: /*
                   12718:  * this is the _only_ way to reliably handle
                   12719:  * variable args with an ANSI compiler
                   12720:  */
                   12721: #ifdef __STDC__
                   12722: /* VARARGS */ int
                   12723: fptreef(FILE *f, char *fmt, ...)
                   12724: {
                   12725: #else
                   12726: fptreef(va_alist) 
                   12727:   va_dcl
                   12728: {
                   12729:   FILE *f;
                   12730:   char *fmt;
                   12731: #endif
                   12732:   va_list      va;
                   12733: 
                   12734: #ifdef __STDC__
                   12735:   va_start(va, fmt);
                   12736: #else
                   12737:   va_start(va);
                   12738:   f = va_arg(va, FILE *);
                   12739:   fmt = va_arg(va, char *);
                   12740: #endif
                   12741:   
                   12742:   vfptreef(f, fmt, va);
                   12743:   va_end(va);
                   12744:   return 0;
                   12745: }
                   12746: 
                   12747: /* VARARGS */ int
                   12748: #ifdef __STDC__
                   12749: snptreef(char *s, int n, char *fmt, ...)
                   12750: {
                   12751: #else
                   12752: snptreef(va_alist)
                   12753:   va_dcl
                   12754: {
                   12755:   char *s;
                   12756:   int n;
                   12757:   char *fmt;
                   12758: #endif
                   12759:   va_list va;
                   12760: 
                   12761: #ifdef __STDC__
                   12762:   va_start(va, fmt);
                   12763: #else
                   12764:   va_start(va);
                   12765:   s = va_arg(va, char *);
                   12766:   n = va_arg(va, int);
                   12767:   fmt = va_arg(va, char *);
                   12768: #endif
                   12769: 
                   12770:   snpf_s = s;
                   12771:   snpf_n = n;
                   12772:   vfptreef(FSTRING, fmt, va);
                   12773:   tputc('\0', FSTRING);
                   12774:   va_end(va);
                   12775:   return 0;
                   12776: }
                   12777: 
                   12778: 
                   12779: vfptreef(f, fmt, va)
                   12780:        register FILE *f;
                   12781:        register char *fmt;
                   12782:        register va_list va;
                   12783: {
                   12784:        register int c;
                   12785: 
                   12786:        while ((c = *fmt++))
                   12787:            if (c == '%') {
                   12788:                register long n;
                   12789:                register char *p;
                   12790:                int neg;
                   12791: 
                   12792:                switch ((c = *fmt++)) {
                   12793:                  case 'c':
                   12794:                        tputc(va_arg(va, int), f);
                   12795:                        break;
                   12796:                  case 's':
                   12797:                        p = va_arg(va, char *);
                   12798:                        while (*p)
                   12799:                                tputc(*p++, f);
                   12800:                        break;
                   12801:                  case 'S':     /* word */
                   12802:                        p = va_arg(va, char *);
                   12803:                        tputS(p, f);
                   12804:                        break;
                   12805:                  case 'd': case 'u': /* decimal */
                   12806:                        n = (c == 'd') ? va_arg(va, int) : va_arg(va, unsigned int);
                   12807:                        neg = c=='d' && n<0;
                   12808:                        p = ulton((neg) ? -n : n, 10);
                   12809:                        if (neg)
                   12810:                                *--p = '-';
                   12811:                        while (*p)
                   12812:                                tputc(*p++, f);
                   12813:                        break;
                   12814:                  case 'T':     /* format tree */
                   12815:                        ptree(va_arg(va, struct op *), f);
                   12816:                        break;
                   12817:                  case ';':     /* newline or ; */
                   12818:                        p = (f == FSTRING) ? "; " : "\n";
                   12819:                        while (*p)
                   12820:                                tputc(*p++, f);
                   12821:                        break;
                   12822:                  default:
                   12823:                        tputc(c, f);
                   12824:                        break;
                   12825:                }
                   12826:            } else
                   12827:                tputc(c, f);
                   12828: }
                   12829: 
                   12830: /*
                   12831:  * copy tree (for function definition)
                   12832:  */
                   12833: 
                   12834: static struct ioword **iocopy();
                   12835: 
                   12836: struct op *
                   12837: tcopy(t, ap)
                   12838:        register struct op *t;
                   12839:        Area *ap;
                   12840: {
                   12841:        register struct op *r;
                   12842:        register char **tw, **rw;
                   12843: 
                   12844:        if (t == NULL)
                   12845:                return NULL;
                   12846: 
                   12847:        r = (struct op *) alloc(sizeof(struct op), ap);
                   12848: 
                   12849:        r->type = t->type;
                   12850: 
                   12851:        /* this will copy function and for identifiers quite accidently */
                   12852:        r->str = (t->str == NULL) ? NULL : wdcopy(t->str, ap);
                   12853: 
                   12854:        if (t->vars == NULL)
                   12855:                r->vars = NULL;
                   12856:        else {
                   12857:                for (tw = t->vars; *tw++ != NULL; )
                   12858:                        ;
                   12859:                rw = r->vars = (char **)
                   12860:                        alloc((int)(tw - t->vars) * sizeof(*tw), ap);
                   12861:                for (tw = t->vars; *tw != NULL; )
                   12862:                        *rw++ = wdcopy(*tw++, ap);
                   12863:                *rw = NULL;
                   12864:        }
                   12865: 
                   12866:        if (t->args == NULL)
                   12867:                r->args = NULL;
                   12868:        else {
                   12869:                for (tw = t->args; *tw++ != NULL; )
                   12870:                        ;
                   12871:                rw = r->args = (char **)
                   12872:                        alloc((int)(tw - t->args) * sizeof(*tw), ap);
                   12873:                for (tw = t->args; *tw != NULL; )
                   12874:                        *rw++ = wdcopy(*tw++, ap);
                   12875:                *rw = NULL;
                   12876:        }
                   12877: 
                   12878:        r->ioact = (t->ioact == NULL) ? NULL : iocopy(t->ioact, ap);
                   12879: 
                   12880:        r->left = tcopy(t->left, ap);
                   12881:        r->right = tcopy(t->right, ap);
                   12882: 
                   12883:        return r;
                   12884: }
                   12885: 
                   12886: char *
                   12887: wdcopy(wp, ap)
                   12888:        char *wp;
                   12889:        Area *ap;
                   12890: {
                   12891:        size_t len = wdscan(wp, EOS) - wp;
                   12892:        return memcpy(alloc(len, ap), wp, len);
                   12893: }
                   12894: 
                   12895: /* return the position of prefix c in wp plus 1 */
                   12896: char *
                   12897: wdscan(wp, c)
                   12898:        register char *wp;
                   12899:        register int c;
                   12900: {
                   12901:        register int nest = 0;
                   12902: 
                   12903:        while (1)
                   12904:                switch (*wp++) {
                   12905:                  case EOS:
                   12906:                        return wp;
                   12907:                  case CHAR:
                   12908:                  case QCHAR:
                   12909:                        wp++;
                   12910:                        break;
                   12911:                  case OQUOTE:
                   12912:                  case CQUOTE:
                   12913:                        break;
                   12914:                  case OSUBST:
                   12915:                        nest++;
                   12916:                        while (*wp++ != 0)
                   12917:                                ;
                   12918:                        if (*wp != CSUBST)
                   12919:                                wp++;
                   12920:                        break;
                   12921:                  case CSUBST:
                   12922:                        if (c == CSUBST && nest == 0)
                   12923:                                return wp;
                   12924:                        nest--;
                   12925:                        break;
                   12926:                  case COMSUB:
                   12927:                        while (*wp++ != 0)
                   12928:                                ;
                   12929:                        break;
                   12930:                }
                   12931: }
                   12932: 
                   12933: static struct ioword **
                   12934: iocopy(iow, ap)
                   12935:        register struct ioword **iow;
                   12936:        Area *ap;
                   12937: {
                   12938:        register struct ioword **ior;
                   12939:        register int i;
                   12940: 
                   12941:        for (ior = iow; *ior++ != NULL; )
                   12942:                ;
                   12943:        ior = (struct ioword **) alloc((int)(ior - iow) * sizeof(*ior), ap);
                   12944: 
                   12945:        for (i = 0; iow[i] != NULL; i++) {
                   12946:                register struct ioword *p, *q;
                   12947: 
                   12948:                p = iow[i];
                   12949:                q = (struct ioword *) alloc(sizeof(*p), ap);
                   12950:                ior[i] = q;
                   12951:                *q = *p;
                   12952:                if (p->name != NULL)
                   12953:                        q->name = wdcopy(p->name, ap);
                   12954:        }
                   12955:        ior[i] = NULL;
                   12956: 
                   12957:        return ior;
                   12958: }
                   12959: 
                   12960: /*
                   12961:  * free tree (for function definition)
                   12962:  */
                   12963: 
                   12964: static void iofree();
                   12965: 
                   12966: void
                   12967: tfree(t, ap)
                   12968:        register struct op *t;
                   12969:        Area *ap;
                   12970: {
                   12971:        register char **w;
                   12972: 
                   12973:        if (t == NULL)
                   12974:                return;
                   12975: 
                   12976:        if (t->str != NULL)
                   12977:                afree((void*)t->str, ap);
                   12978: 
                   12979:        if (t->vars != NULL) {
                   12980:                for (w = t->vars; *w != NULL; w++)
                   12981:                        afree((void*)*w, ap);
                   12982:                afree((void*)t->vars, ap);
                   12983:        }
                   12984: 
                   12985:        if (t->args != NULL) {
                   12986:                for (w = t->args; *w != NULL; w++)
                   12987:                        afree((void*)*w, ap);
                   12988:                afree((void*)t->args, ap);
                   12989:        }
                   12990: 
                   12991:        if (t->ioact != NULL)
                   12992:                iofree(t->ioact, ap);
                   12993: 
                   12994:        tfree(t->left, ap);
                   12995:        tfree(t->right, ap);
                   12996: 
                   12997:        afree((void*)t, ap);
                   12998: }
                   12999: 
                   13000: static void
                   13001: iofree(iow, ap)
                   13002:        struct ioword **iow;
                   13003:        Area *ap;
                   13004: {
                   13005:        register struct ioword **iop;
                   13006:        register struct ioword *p;
                   13007: 
                   13008:        for (iop = iow; (p = *iop++) != NULL; ) {
                   13009:                if (p->name != NULL)
                   13010:                        afree((void*)p->name, ap);
                   13011:                afree((void*)p, ap);
                   13012:        }
                   13013: }
                   13014: 
                   13015: ./pdksh/sh/ChangeLog   644    653   1762       23617  5243743674  11634 0ustar  hluThu Aug 13 00:00:42 1992  Simon J. Gerraty  (sjg@zen)
                   13016: 
                   13017:        * setstr(), varsub(): be robust when given dud args.
                   13018: 
                   13019: Wed Aug 12 23:56:29 1992  Simon J. Gerraty  (sjg@zen)
                   13020: 
                   13021:        * Fixed build problem when COMPLEX_HISTORY is not defined.
                   13022:        * don't make COMPLETE_LIST the default, add 
                   13023:                bind '^[^['=complete-list
                   13024:        in .kshrc if desired.
                   13025: 
                   13026: 
                   13027: Mon Aug  3 22:41:17 1992  Simon J. Gerraty  (sjg@zen)
                   13028: 
                   13029:        * emacs.c: correctly bind <ESC><erase>.
                   13030:        * var.c: treat COLUMNS and FCEDIT as special.
                   13031: 
                   13032: Sat Aug  1 17:17:02 1992  Simon J. Gerraty  (sjg@zen)
                   13033: 
                   13034:        * Incorporated massive contribution from Peter Collinson
                   13035:        includes new features (refer to ../Changes.pc) and support for
                   13036:        BSDI's BSD/386.
                   13037: 
                   13038:        * emacs.c: new command complete-list provided by
                   13039:        [email protected] this nicer than the standard ksh
                   13040:        file completion.  Define COMPLETE_LIST to bind this to <ESC><ESC>
                   13041:        by default.
                   13042: 
                   13043: Sat May 30 15:44:56 1992  Simon J. Gerraty  (sjg@zen)
                   13044: 
                   13045:        * added flag XXWHL in tree.h, used by execute() when calling
                   13046:        exchild() to indicate that stdin should not be invalidated.  This
                   13047:        corrects handling of:  
                   13048:                 ls | while read f; do ls -l $f; done
                   13049: 
                   13050:        Thanks to Bruce Momjian for tracking down the fault.
                   13051: 
                   13052: Tue May 12 19:23:17 1992  Simon J. Gerraty  (sjg@zen)
                   13053: 
                   13054:        * Fix bug in init_editmode() if EMACS and VI are not both defined.
                   13055: 
                   13056: Sun May  3 17:47:54 1992  Simon J. Gerraty  (sjg@zen)
                   13057: 
                   13058:        * sigact.c:  allow force build if USE_* defined.
                   13059:        * main.c: call init_editmode() _after_ processing /etc/profile.
                   13060:        * jobs.c: ensure SA_RESTART is defined.
                   13061: 
                   13062: Sat Apr 25 00:20:51 1992  Simon J. Gerraty  (sjg@zen)
                   13063: 
                   13064:        * Implemented a simple history file.
                   13065:        The default file is "$HOME/.pdksh_hist" but can be changed by
                   13066:        setting HISTFILE in any of /etc/profile,.profile or .kshrc.
                   13067:        The format is trivial - one line per history item.  
                   13068:        You can creat a set history file, by making it read-only.
                   13069:        History is only saved during wrap-up and only if the file is
                   13070:        writeable.  NOTE: if writeable the file is OVERWRITTEN.
                   13071: 
                   13072: Fri Apr 24 22:22:04 1992  Simon J Gerraty  (sjg@zen)
                   13073: 
                   13074:        * sigact.c: New file.
                   13075:        An implementation of sigaction() and freinds, which simply
                   13076:        interfaces to BSD's setsigmask() et al, BSD4.1's setsig() or plain
                   13077:        old signal(2).  It attempts to use the most useful available.
                   13078:        If it thinks the system really has sigaction() it compiles to
                   13079:        noting, and its header sigact.h does nothing.
                   13080:        At present all use of sigaction is bounded by USE_SIGACT, if/when
                   13081:        this approach appears to work, the alternatives will be withdrawn.
                   13082: 
                   13083: Fri Apr 24 10:42:40 1992  Simon J Gerraty  (sjg@taureau)
                   13084: 
                   13085:        * Added support for sigaction and friends!, turns out sigset() 
                   13086:        et al just don't handle job control.  Define USE_SIGACT if you
                   13087:        have sigaction().  Job control now works on this System V machine
                   13088:        (Bull DPX/2).
                   13089: 
                   13090:        * getsc_(lex.c), x_getc(edit.c):  Added goto's! to allow the
                   13091:        read() calls to be retried (on systems that don't do it
                   13092:        automatically) if the read() was interrupted by a SIGCHLD
                   13093:        (sigchld_caught > 0).  This was the cause of the problem with an
                   13094:        async child terminating the shell on System V.
                   13095: 
                   13096: Wed Apr 22 14:57:01 1992  Simon J Gerraty  (sjg@taureau)
                   13097: 
                   13098:        * exchild(jobs.c): block SIGCHLD when fork()ing, until safe to
                   13099:        receive.
                   13100: 
                   13101:        * Added support? for sigset() and friends.  Allow JOBS to work on
                   13102:        System V machines.  This does NOT work right yet.
                   13103:        With JOBS defined, an async process terminates the shell when it
                   13104:        (the child) exits, and ^Z does nothing!  
                   13105: 
                   13106: Tue Apr 21 15:18:08 1992  Simon J. Gerraty  (sjg@sun0)
                   13107: 
                   13108:        * removed const qualifyer from setctypes() 1st arg, as gcc-2.1
                   13109:        generates incorrect code for this function.  This is a temperary
                   13110:        hack until gcc is fixed.
                   13111: 
                   13112:        * do not install std/stdc/stdarg.h in std/h, any compiler that
                   13113:        will use stdarg.h should have one.
                   13114: 
                   13115: Sun Apr 19 20:16:32 1992  Simon J. Gerraty  (sjg@zen)
                   13116: 
                   13117:        * added support of stdargs to tree.c and _fixed_ the use of
                   13118:        varargs. 
                   13119: 
                   13120: Sat Apr 18 16:35:48 1992  Simon J. Gerraty  (sjg@zen)
                   13121: 
                   13122:        * x_read(edit.c): added logic to check $EDITOR etc.
                   13123: 
                   13124: 
                   13125: Fri, 10 Jan 92 13:13:52          Bullseye Software  (sumax!polari!bullseye)
                   13126: 
                   13127:        * alloc.c:afreeall() references memory it has already deallocated.
                   13128: 
                   13129: Wed, 1 Jan 92 20:03:55 Bert Gijsbers ([email protected])
                   13130: 
                   13131:        * expand(eval.c):  PS1='${PWD##/*/}[!]% ' prints also characters
                   13132:        with ascii = 128 
                   13133: 
                   13134:        * main(main.c): Testing whether the first letter of argv[0] is a
                   13135:        '-' does not work when ksh reads .kshrc.
                   13136: 
                   13137: Sun, 29 Dec 91 20:05:02  Bert Gijsbers ([email protected])
                   13138: 
                   13139:        * Support for Minix.
                   13140: 
                   13141: Wed, 11 Dec 91 12:41:31        Kees J. Bot ([email protected])
                   13142: 
                   13143:        * fixes for sun3 with 4.1.1
                   13144: 
                   13145: Wed, 4 Dec 91 15:53:43  Reg Quinton ([email protected])
                   13146: 
                   13147:        * fixes for SGI
                   13148: 
                   13149: Mon Nov 25 12:36:42 1991  Simon J. Gerraty  (sjg at zen)
                   13150: 
                   13151:        * stdh.h:  make sure FD_CLEXEC is defined if we support F_SETFD.
                   13152:        
                   13153:        * emacs.c: Attempt to make alloc() of x_tab acceptible to more
                   13154:        compilers.  Not 100% yet.
                   13155:        
                   13156: Sat Nov 23 14:31:44 1991  Simon J. Gerraty  (sjg at zen)
                   13157: 
                   13158:        * Improved fd_clexec handling for systems that don't have
                   13159:        an F_SETFD fcntl().  The new arrangement will not blow up if an
                   13160:        attempt is made to fd_clexec a fd above MAXFD (64 by default).
                   13161:        main.c:main()  and io.c:savefd() now simply call
                   13162:        exec.c:fd_clexec(). 
                   13163: 
                   13164: Fri Nov 22 11:24:57 1991  Simon J. Gerraty  (sjg at zen)
                   13165: 
                   13166:        * Since many people had problems using the headers and libraries
                   13167:        in std/*, modified sh/* so that they can be compiled in the
                   13168:        absence of std/*.  This requires putting in some fixes that I had
                   13169:        left out from my 3.2 version.  Particularly, catering for systems
                   13170:        that do not have F_SETFD.
                   13171: 
                   13172:        * exec.c:
                   13173:        Added fd_clexec array for tracking fd's to close in child after
                   13174:        fork().  This is avoid wasting fd's on systems that don't have
                   13175:        F_SETFD.
                   13176: 
                   13177:        * jobs.c:
                   13178:        Allow Sun's and perhaps other BSD systems to define WAIT_T to be
                   13179:        union wait and thus use their native status handling for children.
                   13180: 
                   13181:        * The file sh/MACHINES now tracks systems the shell has been
                   13182:        compiled on.
                   13183: 
                   13184: 
                   13185: Sat Nov  9 14:57:30 1991  Simon J. Gerraty  (sjg at zen)
                   13186: 
                   13187:        * Release version 4.1 as a new base line.
                   13188: 
                   13189: Thu Nov  7 23:11:25 1991  Simon J. Gerraty  (sjg at zen)
                   13190: 
                   13191:        * John R MacMillan suppied a fix for a bug in yylex() that was the
                   13192:        cause of several odd problems such as:
                   13193:                $ foo=echo
                   13194:                $ $foo bar
                   13195:                bar: not found
                   13196:                $ pwd
                   13197:                $ /local/src/pdksh
                   13198:                $ $foo bar
                   13199:                bar
                   13200:                $
                   13201: 
                   13202: Sun Sep 15 23:19:27 1991  Simon J. Gerraty  (sjg at zen)
                   13203: 
                   13204:        * emacs.c:
                   13205:        Added function x_lastcp() which returns a pointer to that char in
                   13206:        the edit buffer that will be the last displayed on the screen.
                   13207:        Thus:
                   13208: 
                   13209:           cp = x_lastcp();
                   13210:          while (cp > xcp)
                   13211:             x_bs(*--cp);
                   13212:        
                   13213:        Will correctly position the cursor on the screen (regardless of
                   13214:        TABs etc in the buffer).  The previous method got out of sync if
                   13215:        there were any TABs to display.
                   13216: 
                   13217: Wed Aug  7 11:26:55 1991  Simon J. Gerraty  (sjg at sun0)
                   13218: 
                   13219:        * jobs.c:
                   13220:        The Sun SPARCstation 2 was proving extremely unreliable using ksh.
                   13221:        After puting traces in jobs.c, it turns out the problem was
                   13222:        multiple SIGCHLD events happening too quickly causing the handler
                   13223:        to be interupted and thus not recognise the job that it had just
                   13224:        reaped was one of its own.  Having done the waitpid(), but not
                   13225:        adjusted the job table entry, j_waitj() would loop forever waiting
                   13226:        for a job to finnish (that had already done so!)
                   13227:        Solution was to have the SIGCHLD handler simply record the events
                   13228:        by inrcrementing sigchld_caught.  The actual reaping is now done
                   13229:        in a new funtion j_reapchld(), which does what the old signal
                   13230:        handler did but blocks SIGCHLD while scanning the job table.
                   13231:        j_waitj() calls j_reapchld() when sigchld_caught is non-zero.
                   13232:        The SS2 is now much more reliable...
                   13233: 
                   13234:        * trace.c:
                   13235:        Added my simple _TRACE facility (used to track the j_waitj
                   13236:        problem).  Simply -DUSE_TRACE for it to have effect.  If USE_TRACE
                   13237:        is undefined, calls to _TRACE() expand to while(0) which an
                   13238:        optimizer will usually remove.  sh.h now includes trace.h
                   13239: 
                   13240: Mon Jun 10 10:27:14 1991  Simon J. Gerraty  (sjg at zen)
                   13241: 
                   13242:        * emacs.c:
                   13243:        A couple of assignments (xbp = xbuf) were not migrated from the
                   13244:        3.2 version.  Caused an anoying bug when retrieving history
                   13245:        commands. 
                   13246: 
                   13247: Mon May 27 12:50:20 1991  Simon J. Gerraty  (sjg at sun0)
                   13248: 
                   13249:        * added fixes supplied by Mike Jetzer:
                   13250:        These relate mainly to vi mode.  See Changes.mlj
                   13251: 
                   13252:        * c_sh.c c_exit():
                   13253:        Modified behavior to not imediately exit if there are stopped
                   13254:        jobs.  A subsequent exit will kill any jobs left and terminate the
                   13255:        shell. 
                   13256: 
                   13257: Fri May 24 15:20:10 1991  Simon J. Gerraty  (sjg at sun0)
                   13258: 
                   13259:        * edit.h:
                   13260:        Cleaned up prototypes.  Built shell on sun3.
                   13261:        While gcc-1.39 builds the ksh ok on the 386i, on the sun3 jobs
                   13262:        don't work correctly - any non-builtin command gets stopped and
                   13263:        put into the background.  Had same problem with 3.2, using
                   13264:        /usr/bin/cc works fine.
                   13265: 
                   13266: Thu May 23 13:45:20 1991  Simon J. Gerraty  (sjg at sun0)
                   13267: 
                   13268:        * migrated my 3.2 edit.c changes to the new shell.
                   13269:        Affects edit.c, emacs.c
                   13270:        Added edit.h which is now included by edit.c,emacs.c and vi.c
                   13271:        
                   13272:        * vi.c:
                   13273:        Fixed handling of '!' in prompt by using pprompt() as in emacs.c
                   13274: 
                   13275:        * std/stdc/vprintf.c:
                   13276:        Fixed bug in output of left '0' padded unsigned numbers was
                   13277:        always padding with ' ' which left a space in ksh's temp file
                   13278:        names.  This prevented fc -l from working.
                   13279: 
                   13280: Here is my 3.2 ChangeLog:
                   13281: Fri Mar 22 16:50:14 1991  Simon J. Gerraty  (sjg at sun0)
                   13282: 
                   13283:        * edit.c:
                   13284:        Added x_set_arg() and x_prev_histword().
                   13285:        x_set_arg() handles 'ESC''0-9' type args which are used by word
                   13286:        related commands.
                   13287:        x_prev_histword() recovers the last (default) or sepcified arg
                   13288:        word from the previous command line.  Bound to ESC. and ESC_ to be
                   13289:        compatible with real ksh.
                   13290: 
                   13291: Tue Feb 26 14:16:17 1991 Simon J. Gerraty  (sjg at zen)
                   13292: 
                   13293:        * edit.c:
                   13294:        Changes to handle editing of command lines longer than $COLUMNS in
                   13295:        a manner compatible with real ksh.
                   13296: 
                   13297: Mon Feb 25 12:20:36 1991 Simon J. Gerraty  (sjg at sun0)
                   13298: 
                   13299:        * var.c,table.h:
                   13300:        Implemented $RANDOM
                   13301:        Some scripts use [ "$RANDOM" != "$RANDOM" ] to check for ksh. 
                   13302: 
                   13303: Wed Feb 20 12:20:36 1991 Simon J. Gerraty  (sjg at sun0)
                   13304: 
                   13305:        Changes so that shell will compile on sun386i.
                   13306: 
                   13307:        * exec.c,main.c,io.c:
                   13308:        Handle the case where FD_CLEXEC isn't defined.
                   13309: 
                   13310:        * jobs.c:
                   13311:        SunOS has its own ideas about job status etc.
                   13312: 
                   13313:        * tree.c:
                   13314:        Fixed conflict between varargs and stdarg.
                   13315: 
                   13316: 
                   13317: 
                   13318: 
                   13319: ./pdksh/sh/alloc.c   644    653   1762       11333  5243743566  11310 0ustar  hlu/*
                   13320:  * area-based allocation built on malloc/free
                   13321:  */
                   13322: 
                   13323: #ifndef lint
                   13324: static char *RCSid = "$Id: alloc.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   13325: #endif
                   13326: 
                   13327: #include "stdh.h"
                   13328: #include <setjmp.h>
                   13329: #include "sh.h"
                   13330: 
                   13331: #define        ICELLS  100             /* number of Cells in small Block */
                   13332: 
                   13333: typedef union Cell Cell;
                   13334: typedef struct Block Block;
                   13335: 
                   13336: /*
                   13337:  * The Cells in a Block are organized as a set of objects.
                   13338:  * Each object (pointed to by dp) begins with a size in (dp-1)->size,
                   13339:  * followed with "size" data Cells.  Free objects are
                   13340:  * linked together via dp->next.
                   13341:  */
                   13342: 
                   13343: union Cell {
                   13344:        size_t  size;
                   13345:        union Cell   *next;
                   13346:        struct {int _;} junk;   /* alignment */
                   13347: };
                   13348: 
                   13349: struct Block {
                   13350:        struct Block  *next;            /* list of Blocks in Area */
                   13351:        union Cell   *free;             /* object free list */
                   13352:        union Cell   *last;             /* &b.cell[size] */
                   13353:        union Cell      cell [1];       /* [size] Cells for allocation */
                   13354: };
                   13355: 
                   13356: Block aempty = {&aempty, aempty.cell, aempty.cell};
                   13357: 
                   13358: /* create empty Area */
                   13359: Area *
                   13360: ainit(ap)
                   13361:        register Area *ap;
                   13362: {
                   13363:        ap->free = &aempty;
                   13364:        return ap;
                   13365: }
                   13366: 
                   13367: /* free all object in Area */
                   13368: void
                   13369: afreeall(ap)
                   13370:        register Area *ap;
                   13371: {
                   13372:        register Block *bp;
                   13373:        register Block *tmp;
                   13374: 
                   13375:        bp = ap->free;
                   13376:        if (bp != NULL && bp != &aempty) {
                   13377:                do {
                   13378:                        tmp = bp->next;
                   13379:                        free((void*)bp);
                   13380:                        bp = tmp;
                   13381:                } while (bp != ap->free);
                   13382:                ap->free = &aempty;
                   13383:        }
                   13384: }
                   13385: 
                   13386: /* allocate object from Area */
                   13387: void *
                   13388: alloc(size, ap)
                   13389:        size_t size;
                   13390:        register Area *ap;
                   13391: {
                   13392:        int cells, split;
                   13393:        register Block *bp;
                   13394:        register Cell *dp, *fp, *fpp;
                   13395: 
                   13396:        if (size <= 0) {
                   13397:                aerror(ap, "allocate bad size");
                   13398:                return NULL;
                   13399:        }
                   13400:        cells = (unsigned)(size - 1) / sizeof(Cell) + 1;
                   13401: 
                   13402:        /* find Cell large enough */
                   13403:        for (bp = ap->free; ; bp = bp->next) {
                   13404:                for (fpp = NULL, fp = bp->free;
                   13405:                     fp != bp->last; fpp = fp, fp = fpp->next)
                   13406:                        if ((fp-1)->size >= cells)
                   13407:                                goto Found;
                   13408: 
                   13409:                /* wrapped around Block list, create new Block */
                   13410:                if (bp->next == ap->free) {
                   13411:                        bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells]));
                   13412:                        if (bp == NULL) {
                   13413:                                aerror(ap, "cannot allocate");
                   13414:                                return NULL;
                   13415:                        }
                   13416:                        if (ap->free == &aempty)
                   13417:                                bp->next = bp;
                   13418:                        else {
                   13419:                                bp->next = ap->free->next;
                   13420:                                ap->free->next = bp;
                   13421:                        }
                   13422:                        bp->last = bp->cell + ICELLS + cells;
                   13423:                        fp = bp->free = bp->cell + 1; /* initial free list */
                   13424:                        (fp-1)->size = ICELLS + cells - 1;
                   13425:                        fp->next = bp->last;
                   13426:                        fpp = NULL;
                   13427:                        break;
                   13428:                }
                   13429:        }
                   13430:   Found:
                   13431:        ap->free = bp;
                   13432:        dp = fp;                /* allocated object */
                   13433:        split = (dp-1)->size - cells;
                   13434:        if (split < 0)
                   13435:                aerror(ap, "allocated object too small");
                   13436:        if (--split <= 0) {     /* allocate all */
                   13437:                fp = fp->next;
                   13438:        } else {                /* allocate head, free tail */
                   13439:                (fp-1)->size = cells;
                   13440:                fp += cells + 1;
                   13441:                (fp-1)->size = split;
                   13442:                fp->next = dp->next;
                   13443:        }
                   13444:        if (fpp == NULL)
                   13445:                bp->free = fp;
                   13446:        else
                   13447:                fpp->next = fp;
                   13448:        return (void*) dp;
                   13449: }
                   13450: 
                   13451: /* change size of object -- like realloc */
                   13452: void *
                   13453: aresize(ptr, size, ap)
                   13454:        register void *ptr;
                   13455:        size_t size;
                   13456:        Area *ap;
                   13457: {
                   13458:        int cells;
                   13459:        register Cell *dp = (Cell*) ptr;
                   13460: 
                   13461:        if (size <= 0) {
                   13462:                aerror(ap, "allocate bad size");
                   13463:                return NULL;
                   13464:        }
                   13465:        cells = (unsigned)(size - 1) / sizeof(Cell) + 1;
                   13466: 
                   13467:        if (dp == NULL || (dp-1)->size < cells) { /* enlarge object */
                   13468:                register Cell *np;
                   13469:                register int i;
                   13470:                void *optr = ptr;
                   13471: 
                   13472:                ptr = alloc(size, ap);
                   13473:                np = (Cell*) ptr;
                   13474:                if (dp != NULL)
                   13475:                        for (i = (dp-1)->size; i--; )
                   13476:                                *np++ = *dp++;
                   13477:                afree(optr, ap);
                   13478:        } else {                /* shrink object */
                   13479:                int split;
                   13480: 
                   13481:                split = (dp-1)->size - cells;
                   13482:                if (--split <= 0) /* cannot split */
                   13483:                        ;
                   13484:                else {          /* shrink head, free tail */
                   13485:                        (dp-1)->size = cells;
                   13486:                        dp += cells + 1;
                   13487:                        (dp-1)->size = split;
                   13488:                        afree((void*)dp, ap);
                   13489:                }
                   13490:        }
                   13491:        return (void*) ptr;
                   13492: }
                   13493: 
                   13494: void
                   13495: afree(ptr, ap)
                   13496:        void *ptr;
                   13497:        register Area *ap;
                   13498: {
                   13499:        register Block *bp;
                   13500:        register Cell *fp, *fpp;
                   13501:        register Cell *dp = (Cell*)ptr;
                   13502: 
                   13503:        /* find Block containing Cell */
                   13504:        for (bp = ap->free; ; bp = bp->next) {
                   13505:                if (bp->cell <= dp && dp < bp->last)
                   13506:                        break;
                   13507:                if (bp->next == ap->free) {
                   13508:                        aerror(ap, "freeing with invalid area");
                   13509:                        return;
                   13510:                }
                   13511:        }
                   13512: 
                   13513:        /* find position in free list */
                   13514:        for (fpp = NULL, fp = bp->free; fp < dp; fpp = fp, fp = fpp->next)
                   13515:                ;
                   13516: 
                   13517:        if (fp == dp) {
                   13518:                aerror(ap, "freeing free object");
                   13519:                return;
                   13520:        }
                   13521: 
                   13522:        /* join object with next */
                   13523:        if (dp + (dp-1)->size == fp-1) { /* adjacent */
                   13524:                (dp-1)->size += (fp-1)->size + 1;
                   13525:                dp->next = fp->next;
                   13526:        } else                  /* non-adjacent */
                   13527:                dp->next = fp;
                   13528: 
                   13529:        /* join previous with object */
                   13530:        if (fpp == NULL)
                   13531:                bp->free = dp;
                   13532:        else if (fpp + (fpp-1)->size == dp-1) { /* adjacent */
                   13533:                (fpp-1)->size += (dp-1)->size + 1;
                   13534:                fpp->next = dp->next;
                   13535:        } else                  /* non-adjacent */
                   13536:                fpp->next = dp;
                   13537: }
                   13538: 
                   13539: 
                   13540: #if TEST_ALLOC
                   13541: 
                   13542: Area a;
                   13543: 
                   13544: main(int argc, char **argv) {
                   13545:        int i;
                   13546:        char *p [9];
                   13547: 
                   13548:        ainit(&a);
                   13549:        for (i = 0; i < 9; i++) {
                   13550:                p[i] = alloc(124, &a);
                   13551:                printf("alloc: %x\n", p[i]);
                   13552:        }
                   13553:        for (i = 1; i < argc; i++)
                   13554:                afree(p[atoi(argv[i])], &a);
                   13555:        afreeall(&a);
                   13556:        return 0;
                   13557: }
                   13558: 
                   13559: void aerror(Area *ap, const char *msg) {
                   13560:        abort();
                   13561: }
                   13562: 
                   13563: #endif
                   13564: 
                   13565: ./pdksh/sh/expr.c   644    653   1762       11336  5243743574  11176 0ustar  hlu/*
                   13566:  * Korn expression evaluation
                   13567:  */
                   13568: 
                   13569: #ifndef lint
                   13570: static char *RCSid = "$Id: expr.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   13571: #endif
                   13572: 
                   13573: #include "stdh.h"
                   13574: #include <errno.h>
                   13575: #include <setjmp.h>
                   13576: #include "sh.h"
                   13577: 
                   13578: #define        ef      else if         /* fashion statement */
                   13579: 
                   13580: #define        VAR     0x01
                   13581: #define        LIT     0x02
                   13582: #define        LEQ     0x03
                   13583: #define        LNE     0x04
                   13584: #define        LLE     0x05
                   13585: #define        LGE     0x06
                   13586: 
                   13587: static const char *expression; /* expression being evaluated */
                   13588: static const char *tokp;       /* lexical position */
                   13589: static int tok;                        /* token from token() */
                   13590: static struct tbl *val;                /* value from token() */
                   13591: 
                   13592: static struct tbl *asn      ARGS((void));
                   13593: static struct tbl *e6       ARGS((void));
                   13594: static struct tbl *e5       ARGS((void));
                   13595: static struct tbl *e3       ARGS((void));
                   13596: static struct tbl *e2       ARGS((void));
                   13597: static struct tbl *e0       ARGS((void));
                   13598: static void     token       ARGS((void));
                   13599: static struct tbl *tempvar  ARGS((void));
                   13600: static struct tbl *intvar   ARGS((struct tbl *vp));
                   13601: 
                   13602: /*
                   13603:  * parse and evalute expression
                   13604:  */
                   13605: void
                   13606: evalerr(err)
                   13607:        char *err;
                   13608: {
                   13609:        errorf("%s: %s\n", expression, err);
                   13610: }
                   13611: 
                   13612: long
                   13613: evaluate(expr)
                   13614:        const char *expr;
                   13615: {
                   13616:        struct tbl *v;
                   13617: 
                   13618:        expression = tokp = expr;
                   13619:        token();
                   13620:        v = intvar(asn());
                   13621:        if (!(tok == 0))
                   13622:                evalerr("bad expression");
                   13623:        return v->val.i;
                   13624: }
                   13625: 
                   13626: static struct tbl *
                   13627: asn()
                   13628: {
                   13629:        register struct tbl *vl, *vr;
                   13630: 
                   13631:        vr = vl = e6();
                   13632:        if ((tok == '=')) {
                   13633:                Area * olastarea = lastarea;
                   13634:                token();
                   13635:                if ((vl->flag&RDONLY)) /* assign to rvalue */
                   13636:                        evalerr("bad assignment");
                   13637:                vr = intvar(asn());
                   13638:                lastarea = olastarea;
                   13639:                setint(vl, vr->val.i);
                   13640:                if ((vl->flag&INTEGER) && vl->type == 0) /* default base? */
                   13641:                        vl->type = vr->type;
                   13642:        }
                   13643:        return vr;
                   13644: }
                   13645: 
                   13646: static struct tbl *
                   13647: e6()
                   13648: {
                   13649:        register struct tbl *vl, *vr;
                   13650: 
                   13651:        vl = e5();
                   13652:        while ((tok == LEQ) || (tok == LNE)) {
                   13653:                int op = tok;
                   13654:                token();
                   13655:                vl = intvar(vl);
                   13656:                vr = intvar(e5());
                   13657:                vl->val.i = vl->val.i == vr->val.i;
                   13658:                if (op == LNE)
                   13659:                        vl->val.i = ! vl->val.i;
                   13660:        }
                   13661:        return vl;
                   13662: }
                   13663: 
                   13664: static struct tbl *
                   13665: e5()
                   13666: {
                   13667:        register struct tbl *vl, *vr;
                   13668: 
                   13669:        vl = e3();
                   13670:        while ((tok == LLE) || (tok == '<') || (tok == '>') || (tok == LGE)) {
                   13671:                int op = tok;
                   13672:                token();
                   13673:                vl = intvar(vl);
                   13674:                vr = intvar(e3());
                   13675:                if (op == LLE)
                   13676:                        vl->val.i = vl->val.i <= vr->val.i;
                   13677:                ef (op == '<')
                   13678:                        vl->val.i = vl->val.i < vr->val.i;
                   13679:                ef (op == LGE)
                   13680:                        vl->val.i = vl->val.i >= vr->val.i;
                   13681:                ef (op == '>')
                   13682:                        vl->val.i = vl->val.i > vr->val.i;
                   13683:        }
                   13684:        return vl;
                   13685: }
                   13686: 
                   13687: static struct tbl *
                   13688: e3()
                   13689: {
                   13690:        register struct tbl *vl, *vr;
                   13691: 
                   13692:        vl = e2();
                   13693:        while ((tok == '+') || (tok == '-')) {
                   13694:                int op = tok;
                   13695:                token();
                   13696:                vl = intvar(vl);
                   13697:                vr = intvar(e2());
                   13698:                if (op == '+')
                   13699:                        vl->val.i += vr->val.i;
                   13700:                ef (op == '-')
                   13701:                        vl->val.i -= vr->val.i;
                   13702:        }
                   13703:        return vl;
                   13704: }
                   13705: 
                   13706: static struct tbl *
                   13707: e2()
                   13708: {
                   13709:        register struct tbl *vl, *vr;
                   13710: 
                   13711:        vl = e0();
                   13712:        while ((tok == '*') || (tok == '/') || (tok == '%')) {
                   13713:                int op = tok;
                   13714:                token();
                   13715:                vl = intvar(vl);
                   13716:                vr = intvar(e0());
                   13717:                if (op != '*' && vr->val.i == 0)
                   13718:                        evalerr("zero divisor");
                   13719:                if (op == '*')
                   13720:                        vl->val.i *= vr->val.i;
                   13721:                ef (op == '/')
                   13722:                        vl->val.i /= vr->val.i;
                   13723:                ef (op == '%')
                   13724:                        vl->val.i %= vr->val.i;
                   13725:        }
                   13726:        return vl;
                   13727: }
                   13728: 
                   13729: static struct tbl *
                   13730: e0()
                   13731: {
                   13732:        register struct tbl *v;
                   13733: 
                   13734:        if ((tok == '!') || (tok == '-')) {
                   13735:                int op = tok;
                   13736:                token();
                   13737:                v = intvar(e0());
                   13738:                if (op == '!')
                   13739:                        v->val.i = !v->val.i;
                   13740:                ef (op == '-')
                   13741:                        v->val.i = -v->val.i;
                   13742:        } else
                   13743:        if ((tok == '(')) {
                   13744:                token();
                   13745:                v = asn();
                   13746:                if (!(tok == ')'))
                   13747:                        evalerr("missing )");
                   13748:                token();
                   13749:        } else
                   13750:        if ((tok == VAR) || (tok == LIT)) {
                   13751:                v = val;
                   13752:                token();
                   13753:        } else
                   13754:                evalerr("bad expression");
                   13755:        return v;
                   13756: }
                   13757: 
                   13758: static void
                   13759: token()
                   13760: {
                   13761:        register char *cp = (char *) tokp;
                   13762:        register int c, c2;
                   13763: 
                   13764:        /* skip white space */
                   13765:        do c = *cp++;   while (c != '\0' && (c == ' ' || c == '\t'));
                   13766:        tokp = cp-1;
                   13767: 
                   13768:        if (letter(c)) {
                   13769:                for (; letnum(c); c = *cp++)
                   13770:                        ;
                   13771:                c = *--cp;
                   13772:                *cp = 0;
                   13773:                val = global(tokp);
                   13774:                *cp = c;
                   13775:                tok = VAR;
                   13776:        } else
                   13777:        if (digit(c)) {
                   13778:                for (; letnum(c) || c == '#'; c = *cp++)
                   13779:                        ;
                   13780:                c = *--cp;
                   13781:                *cp = 0;
                   13782:                val = tempvar();
                   13783:                setstr(val, tokp);
                   13784:                val->flag |= RDONLY;
                   13785:                *cp = c;
                   13786:                tok = LIT;
                   13787:        } else {
                   13788:                c2 = *cp++;
                   13789:                if (c == '=' && c2 == '=')
                   13790:                        c = LEQ;
                   13791:                ef (c == '!' && c2 == '=')
                   13792:                        c = LNE;
                   13793:                ef (c == '<' && c2 == '=')
                   13794:                                c = LLE;
                   13795:                ef (c == '>' && c2 == '=')
                   13796:                                c = LGE;
                   13797:                else
                   13798:                        cp--;
                   13799:                tok = c;
                   13800:        }
                   13801:        tokp = cp;
                   13802: }
                   13803: 
                   13804: static struct tbl *
                   13805: tempvar()
                   13806: {
                   13807:        register struct tbl *vp;
                   13808: 
                   13809:        vp = (struct tbl*) alloc(sizeof(struct tbl), ATEMP);
                   13810:        lastarea = ATEMP;
                   13811:        vp->flag = ISSET|INTEGER;
                   13812:        vp->type = 0;
                   13813:        vp->name[0] = '\0';
                   13814:        return vp;
                   13815: }
                   13816: 
                   13817: /* cast (string) variable to temporary integer variable */
                   13818: static struct tbl *
                   13819: intvar(vp)
                   13820:        register struct tbl *vp;
                   13821: {
                   13822:        register struct tbl *vq;
                   13823: 
                   13824:        vq = tempvar();
                   13825:        vq->type = 10;
                   13826:        if (strint(vq, vp) == NULL) {
                   13827:                if ((vp->flag&ISSET) && vp->val.s && *(vp->val.s)) {
                   13828:                        evalerr("bad number");
                   13829:                } else {
                   13830:                        vq->flag |= (ISSET|INTEGER);
                   13831:                        vq->type = 10;
                   13832:                        vq->val.i = 0;
                   13833:                }
                   13834:        }
                   13835:        return vq;
                   13836: }
                   13837: 
                   13838: ./pdksh/sh/mail.c   644    653   1762       10267  5302766411  11133 0ustar  hlu/*
                   13839:  * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
                   13840:  * John R. MacMillan
                   13841:  */
                   13842: #ifndef lint
                   13843: static char *RCSid = "$Id: mail.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   13844: #endif
                   13845: 
                   13846: #include "stdh.h"
                   13847: #include <signal.h>
                   13848: #include <errno.h>
                   13849: #include <setjmp.h>
                   13850: #include <sys/stat.h>
                   13851: #include <sys/time.h>
                   13852: #include "sh.h"
                   13853: 
                   13854: #define MBMESSAGE      "you have mail in $_"
                   13855: 
                   13856: typedef struct mbox {
                   13857:        struct mbox    *mb_next;        /* next mbox in list */
                   13858:        char           *mb_path;        /* path to mail file */
                   13859:        char           *mb_msg;         /* to announce arrival of new mail */
                   13860:        unsigned int    mb_size;        /* size of mail file (bytes) */
                   13861: } mbox_t;
                   13862: 
                   13863: struct mailmsg {
                   13864:        char            *msg;           /* Text of message */
                   13865:        struct mailmsg  *next;          /* Next message */
                   13866: };
                   13867: 
                   13868: /*
                   13869:  * $MAILPATH is a linked list of mboxes.  $MAIL is a treated as a
                   13870:  * special case of $MAILPATH, where the list has only one node.  The
                   13871:  * same list is used for both since they are exclusive.
                   13872:  */
                   13873: 
                   13874: static mbox_t  *mplist = NULL;
                   13875: static mbox_t  mbox = { NULL, NULL, NULL, 0 };
                   13876: static long    mlastchkd = 0;  /* when mail was last checked */
                   13877: static struct mailmsg *mmsgs = NULL;   /* Messages to be printed */
                   13878: #if 0
                   13879: static void    munset();               /* free mlist and mval */
                   13880: static mbox_t  *mballoc();             /* allocate a new mbox */
                   13881: static void    maddmsg();
                   13882: #endif
                   13883: static void     munset      ARGS((mbox_t *mlist));
                   13884: static mbox_t * mballoc     ARGS((char *p, char *m));
                   13885: static void     maddmsg     ARGS((mbox_t *mbp));
                   13886: 
                   13887: void
                   13888: mcheck()
                   13889: {
                   13890:        register mbox_t *mbp;
                   13891:        long             now;
                   13892:        struct tbl      *vp, mailcheck;
                   13893:        struct stat      stbuf;
                   13894: 
                   13895:        vp = global("MAILCHECK");
                   13896:        if (!(vp->flag & ISSET) || strint(&mailcheck, vp) == NULL)
                   13897:                return;
                   13898: 
                   13899:        if (mlastchkd == 0)
                   13900:                mlastchkd = time((long *)0);
                   13901: 
                   13902:        if ((now=time((long *)0)) - mlastchkd >= mailcheck.val.i) {
                   13903:                mlastchkd = now;
                   13904:                
                   13905:                vp = global("MAILPATH");
                   13906:                if (vp && (vp->flag & ISSET))
                   13907:                        mbp = mplist;
                   13908:                else if ((vp = global("MAIL")) && (vp->flag & ISSET))
                   13909:                        mbp = &mbox;
                   13910:                else
                   13911:                        mbp = NULL;
                   13912: 
                   13913:                while (mbp) {
                   13914:                        if (stat(mbp->mb_path, &stbuf) == 0 &&
                   13915:                            (stbuf.st_mode & S_IFMT) == S_IFREG) {
                   13916:                                if (mbp->mb_size < stbuf.st_size)
                   13917:                                        maddmsg( mbp );
                   13918:                                mbp->mb_size = stbuf.st_size;
                   13919:                        } else {
                   13920:                                /*
                   13921:                                 * Some mail readers remove the mail
                   13922:                                 * file if all mail is read.  If file
                   13923:                                 * does not exist, assume this is the
                   13924:                                 * case and set size to zero.
                   13925:                                 */
                   13926:                                mbp->mb_size = 0;
                   13927:                        }
                   13928:                        mbp = mbp->mb_next;
                   13929:                }
                   13930:        }
                   13931: }
                   13932: 
                   13933: void
                   13934: mbset(p)
                   13935:        register char   *p;
                   13936: {
                   13937:        struct stat     stbuf;
                   13938: 
                   13939:        if (mbox.mb_msg)
                   13940:                afree((void *)mbox.mb_msg, APERM);
                   13941:        mbox.mb_path = p;
                   13942:        mbox.mb_msg = NULL;
                   13943:        if (stat(p,&stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFREG)
                   13944:                mbox.mb_size = stbuf.st_size;
                   13945:        else
                   13946:                mbox.mb_size = 0;
                   13947: }
                   13948: 
                   13949: void
                   13950: mpset(mptoparse)
                   13951:        register char   *mptoparse;
                   13952: {
                   13953:        register mbox_t *mbp;
                   13954:        register char   *mpath, *mmsg, *mval;
                   13955: 
                   13956:        munset( mplist );
                   13957:        mplist = NULL;
                   13958:        mval = strsave(mptoparse, APERM);
                   13959:        while (mval) {
                   13960:                mpath = mval;
                   13961:                if ((mval = strchr(mval, ':')) != NULL) {
                   13962:                        *mval ='\0', mval++;
                   13963:                }
                   13964:                if ((mmsg = strchr(mpath, '?')) != NULL) {
                   13965:                        *mmsg = '\0', mmsg++;
                   13966:                }
                   13967:                mbp = mballoc(mpath, mmsg);
                   13968:                mbp->mb_next = mplist;
                   13969:                mplist = mbp;
                   13970:        }
                   13971: }
                   13972: 
                   13973: static void
                   13974: munset(mlist)
                   13975: register mbox_t        *mlist;
                   13976: {
                   13977:        register mbox_t *mbp;
                   13978: 
                   13979:        while (mlist != NULL) {
                   13980:                mbp = mlist;
                   13981:                mlist = mbp->mb_next;
                   13982:                if (!mlist)
                   13983:                        afree((void *)mbp->mb_path, APERM);
                   13984:                afree((void *)mbp, APERM);
                   13985:        }
                   13986: }
                   13987: 
                   13988: static mbox_t *
                   13989: mballoc(p, m)
                   13990:        char    *p;
                   13991:        char    *m;
                   13992: {
                   13993:        struct stat     stbuf;
                   13994:        register mbox_t *mbp;
                   13995: 
                   13996:        mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM);
                   13997:        mbp->mb_next = NULL;
                   13998:        mbp->mb_path = p;
                   13999:        mbp->mb_msg = m;
                   14000:        if (stat(mbp->mb_path, &stbuf) == 0 &&
                   14001:           (stbuf.st_mode & S_IFMT) == S_IFREG) {
                   14002:                mbp->mb_size = stbuf.st_size;
                   14003:        } else {
                   14004:                mbp->mb_size = 0;
                   14005:        }
                   14006:        return(mbp);
                   14007: }
                   14008: 
                   14009: void
                   14010: mprint()
                   14011: {
                   14012:        struct mailmsg *mm;
                   14013: 
                   14014:        while ((mm = mmsgs) != NULL) {
                   14015:                shellf( "%s\n", mm->msg );
                   14016:                fflush(shlout);
                   14017:                afree((void *)mm->msg, APERM);
                   14018:                mmsgs = mm->next;
                   14019:                afree((void *)mm, APERM);
                   14020:        }
                   14021: }
                   14022: 
                   14023: static void
                   14024: maddmsg( mbp )
                   14025: mbox_t *mbp;
                   14026: {
                   14027:        struct mailmsg  *message;
                   14028:        struct tbl      *vp;
                   14029: 
                   14030:        message = (struct mailmsg *)alloc(sizeof(struct mailmsg), APERM);
                   14031:        setstr((vp = typeset("_", LOCAL, 0)), mbp->mb_path);
                   14032: 
                   14033:        if (mbp->mb_msg)
                   14034:                message->msg = strsave(substitute(mbp->mb_msg,0),APERM);
                   14035:        else
                   14036:                message->msg = strsave(substitute(MBMESSAGE,0),APERM);
                   14037: 
                   14038:        unset(vp);
                   14039:        message->next = mmsgs;
                   14040:        mmsgs = message;
                   14041: }
                   14042: ./pdksh/sh/misc.c   644    653   1762       15541  5302637123  11141 0ustar  hlu/*
                   14043:  * Miscellaneous functions
                   14044:  */
                   14045: 
                   14046: #ifndef lint
                   14047: static char *RCSid = "$Id: misc.c,v 1.3 1992/08/12 14:15:42 sjg Exp $";
                   14048: #endif
                   14049: 
                   14050: #include "stdh.h"
                   14051: #include <signal.h>
                   14052: #include <errno.h>
                   14053: #include <setjmp.h>
                   14054: #include "sh.h"
                   14055: #include "expand.h"
                   14056: #ifndef NOSTDHDRS
                   14057: # include <limits.h>
                   14058: #else
                   14059: # define UCHAR_MAX     0xFF
                   14060: #endif
                   14061: 
                   14062: char ctypes [UCHAR_MAX+1];     /* type bits for unsigned char */
                   14063: 
                   14064: static char *   cclass      ARGS((char *p, int sub));
                   14065: 
                   14066: /*
                   14067:  * Fast character classes
                   14068:  */
                   14069: void
                   14070: setctypes(s, t)
                   14071:        register /* const */ char *s;
                   14072:        register int t;
                   14073: {
                   14074:        register int i;
                   14075: 
                   14076:        if ((t&C_IFS)) {
                   14077:                for (i = 0; i < UCHAR_MAX+1; i++)
                   14078:                        ctypes[i] &=~ C_IFS;
                   14079:                ctypes[0] |= C_IFS; /* include \0 in C_IFS */
                   14080:        }
                   14081:        ctypes[(unsigned char) *s++] |= t;      /* allow leading \0 in string */
                   14082:        while (*s != 0)
                   14083:                ctypes[(unsigned char) *s++] |= t;
                   14084: }
                   14085: 
                   14086: void
                   14087: initctypes()
                   14088: {
                   14089:        register int c;
                   14090: 
                   14091:        for (c = 'a'; c <= 'z'; c++)
                   14092:                ctypes[c] |= C_ALPHA;
                   14093:        for (c = 'A'; c <= 'Z'; c++)
                   14094:                ctypes[c] |= C_ALPHA;
                   14095:        ctypes['_'] |= C_ALPHA;
                   14096:        setctypes("0123456789", C_DIGIT);
                   14097:        setctypes("\0 \t\n|&;<>()", C_LEX1);
                   14098:        setctypes("*@#!$-?", C_VAR1);
                   14099:        setctypes("=-+?#%", C_SUBOP);
                   14100: }
                   14101: 
                   14102: /* convert unsigned long to base N string */
                   14103: 
                   14104: char *
                   14105: ulton(n, base)
                   14106:        register unsigned long n;
                   14107:        int base;
                   14108: {
                   14109:        register char *p;
                   14110:        static char buf [20];
                   14111: 
                   14112:        p = &buf[sizeof(buf)];
                   14113:        *--p = '\0';
                   14114:        do {
                   14115:                *--p = "0123456789ABCDEF"[n%base];
                   14116:                n /= base;
                   14117:        } while (n != 0);
                   14118:        return p;
                   14119: }
                   14120: 
                   14121: char *
                   14122: strsave(s, ap)
                   14123:        register char *s;
                   14124:        Area *ap;
                   14125: {
                   14126:   return s ? strcpy((char*) alloc((size_t)strlen(s)+1, ap), s) : NULL;
                   14127: }
                   14128: 
                   14129: static struct option {
                   14130:        char *name;
                   14131:        int flag;
                   14132: } options[] = {
                   14133:        {"allexport",   FEXPORT},
                   14134:        {"bgnice",      FBGNICE},
                   14135: #if defined(EDIT) && defined(EMACS)
                   14136:        {"emacs",       FEMACS},
                   14137: #endif
                   14138:        {"errexit",     FERREXIT},
                   14139:        {"hashall",     FHASHALL},
                   14140:        {"ignoreeof",   FIGNEOF},
                   14141:        {"interactive", FTALKING},
                   14142:        {"keyword",     FKEYWORD},
                   14143:        {"markdirs",    FMARKDIRS},
                   14144:        {"monitor",     FMONITOR},
                   14145:        {"noexec",      FNOEXEC},
                   14146:        {"noglob",      FNOGLOB},
                   14147:        {"nounset",     FNOUNSET},
                   14148:        {"privileged",  FPRIVILEGED},
                   14149:        {"stdin",       FSTDIN},
                   14150:        {"trackall",    FHASHALL},
                   14151:        {"verbose",     FVERBOSE},
                   14152: #if defined(EDIT) && defined(VI)
                   14153:        {"vi",          FVI},
                   14154: #endif
                   14155:        {"xtrace",      FXTRACE},
                   14156:        {NULL,          0}
                   14157: };     
                   14158: 
                   14159: /*
                   14160:  * translate -o option into F* constant
                   14161:  */
                   14162: int
                   14163: option(n)
                   14164:        const char *n;
                   14165: {
                   14166:        register struct option *op;
                   14167: 
                   14168:        for (op = options; op->name != NULL; op++)
                   14169:                if (strcmp(op->name, n) == 0)
                   14170:                        return op->flag;
                   14171:        return 0;
                   14172: }
                   14173: 
                   14174: char *
                   14175: getoptions()
                   14176: {
                   14177:        register int c;
                   14178:        char m [26+1];
                   14179:        register char *cp = m;
                   14180: 
                   14181:        for (c = 'a'; c <= 'z'; c++)
                   14182:                if (flag[FLAG(c)])
                   14183:                        *cp++ = (char) c;
                   14184:        *cp = 0;
                   14185:        return strsave(m, ATEMP);
                   14186: }
                   14187: 
                   14188: void
                   14189: printoptions()
                   14190: {
                   14191:        register struct option *op;
                   14192: 
                   14193:        for (op = options; op->name != NULL; op++)
                   14194:                if (flag[op->flag])
                   14195:                        shellf("%s ", op->name);
                   14196:        shellf("\n");
                   14197: }
                   14198:        
                   14199: /* atoi with error detection */
                   14200: 
                   14201: getn(as)
                   14202:        char *as;
                   14203: {
                   14204:        register char *s;
                   14205:        register int n;
                   14206: 
                   14207:        s = as;
                   14208:        if (*s == '-')
                   14209:                s++;
                   14210:        for (n = 0; digit(*s); s++)
                   14211:                n = (n*10) + (*s-'0');
                   14212:        if (*s)
                   14213:                errorf("%s: bad number\n", as);
                   14214:        return (*as == '-') ? -n : n;
                   14215: }
                   14216: 
                   14217: #ifndef linux
                   14218: /*
                   14219:  * stripped down strerror for kill and exec
                   14220:  */
                   14221: char *
                   14222: strerror(i)
                   14223:        int i;
                   14224: {
                   14225:        switch (i) {
                   14226:          case EINVAL:
                   14227:                return "Invalid argument";
                   14228:          case EACCES:
                   14229:                return "Permission denied";
                   14230:          case ESRCH:
                   14231:                return "No such process";
                   14232:          case EPERM:
                   14233:                return "Not owner";
                   14234:          case ENOENT:
                   14235:                return "No such file or directory";
                   14236:          case ENOTDIR:
                   14237:                return "Not a directory";
                   14238:          case ENOEXEC:
                   14239:                return "Exec format error";
                   14240:          case ENOMEM:
                   14241:                return "Not enough memory";
                   14242:          case E2BIG:
                   14243:                return "Argument list too long";
                   14244:          default:
                   14245:                return "Unknown system error";
                   14246:        }
                   14247: }
                   14248: 
                   14249: #endif
                   14250: 
                   14251: /* -------- gmatch.c -------- */
                   14252: 
                   14253: /*
                   14254:  * int gmatch(string, pattern)
                   14255:  * char *string, *pattern;
                   14256:  *
                   14257:  * Match a pattern as in sh(1).
                   14258:  * pattern character are prefixed with MAGIC by expand.
                   14259:  */
                   14260: 
                   14261: static char    *cclass ARGS((char *, int c));
                   14262: 
                   14263: int
                   14264: gmatch(s, p)
                   14265:        register char *s, *p;
                   14266: {
                   14267:        register int sc, pc;
                   14268: 
                   14269:        if (s == NULL || p == NULL)
                   14270:                return 0;
                   14271:        while ((pc = *p++) != 0) {
                   14272:                sc = *s++;
                   14273:                if (pc ==  MAGIC)
                   14274:                        switch (*p++) {
                   14275:                          case '[':
                   14276:                                if (sc == 0 || (p = cclass(p, sc)) == NULL)
                   14277:                                        return (0);
                   14278:                                break;
                   14279: 
                   14280:                          case '?':
                   14281:                                if (sc == 0)
                   14282:                                        return (0);
                   14283:                                break;
                   14284: 
                   14285:                          case '*':
                   14286:                                s--;
                   14287:                                do {
                   14288:                                        if (*p == '\0' || gmatch(s, p))
                   14289:                                                return (1);
                   14290:                                } while (*s++ != '\0');
                   14291:                                return (0);
                   14292: 
                   14293:                          default:
                   14294:                                if (sc != p[-1])
                   14295:                                        return 0;
                   14296:                                break;
                   14297:                        }
                   14298:                else
                   14299:                        if (sc != pc)
                   14300:                                return 0;
                   14301:        }
                   14302:        return (*s == 0);
                   14303: }
                   14304: 
                   14305: static char *
                   14306: cclass(p, sub)
                   14307:        register char *p;
                   14308:        register int sub;
                   14309: {
                   14310:        register int c, d, not, found = 0;
                   14311: 
                   14312:        if ((not = (*p == MAGIC && *++p == NOT)))
                   14313:                p++;
                   14314:        do {
                   14315:                if (*p == MAGIC)
                   14316:                        p++;
                   14317:                if (*p == '\0')
                   14318:                        return NULL;
                   14319:                c = *p;
                   14320:                if (p[1] == '-' && p[2] != ']') {
                   14321:                        d = p[2];
                   14322:                        p++;
                   14323:                } else
                   14324:                        d = c;
                   14325:                if (c == sub || (c <= sub && sub <= d))
                   14326:                        found = 1;
                   14327:        } while (*++p != ']');
                   14328: 
                   14329:        return (found != not) ? p+1 : NULL;
                   14330: }
                   14331: 
                   14332: /* -------- qsort.c -------- */
                   14333: 
                   14334: /*
                   14335:  * quick sort of array of generic pointers to objects.
                   14336:  */
                   14337: 
                   14338: void
                   14339: qsortp(base, n, f)
                   14340:        void **base;            /* base address */
                   14341:        size_t n;               /* elements */
                   14342:        int (*f)();             /* compare function */
                   14343: {
                   14344:        qsort1(base, base + n, f);
                   14345: }
                   14346: 
                   14347: #define        swap2(a, b)     {\
                   14348:        register void *t; t = *(a); *(a) = *(b); *(b) = t;\
                   14349: }
                   14350: #define        swap3(a, b, c)  {\
                   14351:        register void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\
                   14352: }
                   14353: 
                   14354: qsort1(base, lim, f)
                   14355:        void **base, **lim;
                   14356:        int (*f)();
                   14357: {
                   14358:        register void **i, **j;
                   14359:        register void **lptr, **hptr;
                   14360:        size_t n;
                   14361:        int c;
                   14362: 
                   14363:   top:
                   14364:        n = (lim - base) / 2;
                   14365:        if (n == 0)
                   14366:                return;
                   14367:        hptr = lptr = base+n;
                   14368:        i = base;
                   14369:        j = lim - 1;
                   14370: 
                   14371:        for (;;) {
                   14372:                if (i < lptr) {
                   14373:                        if ((c = (*f)(*i, *lptr)) == 0) {
                   14374:                                lptr --;
                   14375:                                swap2(i, lptr);
                   14376:                                continue;
                   14377:                        }
                   14378:                        if (c < 0) {
                   14379:                                i += 1;
                   14380:                                continue;
                   14381:                        }
                   14382:                }
                   14383: 
                   14384:          begin:
                   14385:                if (j > hptr) {
                   14386:                        if ((c = (*f)(*hptr, *j)) == 0) {
                   14387:                                hptr ++;
                   14388:                                swap2(hptr, j);
                   14389:                                goto begin;
                   14390:                        }
                   14391:                        if (c > 0) {
                   14392:                                if (i == lptr) {
                   14393:                                        hptr ++;
                   14394:                                        swap3(i, hptr, j);
                   14395:                                        i = lptr += 1;
                   14396:                                        goto begin;
                   14397:                                }
                   14398:                                swap2(i, j);
                   14399:                                j -= 1;
                   14400:                                i += 1;
                   14401:                                continue;
                   14402:                        }
                   14403:                        j -= 1;
                   14404:                        goto begin;
                   14405:                }
                   14406: 
                   14407:                if (i == lptr) {
                   14408:                        if (lptr-base >= lim-hptr) {
                   14409:                                qsort1(hptr+1, lim, f);
                   14410:                                lim = lptr;
                   14411:                        } else {
                   14412:                                qsort1(base, lptr, f);
                   14413:                                base = hptr+1;
                   14414:                        }
                   14415:                        goto top;
                   14416:                }
                   14417: 
                   14418:                lptr -= 1;
                   14419:                swap3(j, lptr, i);
                   14420:                j = hptr -= 1;
                   14421:        }
                   14422: }
                   14423: 
                   14424: int
                   14425: xstrcmp(p1, p2)
                   14426:        void *p1, *p2;
                   14427: {
                   14428:        return (strcmp((char *)p1, (char *)p2));
                   14429: }
                   14430: 
                   14431: void
                   14432: cleanpath(pwd, dir, clean)
                   14433:        char *pwd, *dir, *clean;
                   14434: {
                   14435:        register char  *s, *d, *p;
                   14436:        char *slash = "/";
                   14437:        register int inslash = 0;
                   14438: 
                   14439:        d = clean;
                   14440:        if (*dir != '/') {
                   14441:                s = pwd;
                   14442:                while (*d++ = *s++)
                   14443:                        ;
                   14444:                if (d >= clean + 2 && *(d - 2) == '/')
                   14445:                        d--;
                   14446:                else
                   14447:                        *(d - 1) = '/';
                   14448:        }
                   14449: 
                   14450:        s = dir;
                   14451:        while (*s) {
                   14452:                if ((*d++ = *s++) == '/' && d > clean + 1) {
                   14453:                        if (*(p = d - 2) == '/') {
                   14454:                                --d;
                   14455:                        } else if (*p == '.') {
                   14456:                                if (*--p == '/') {
                   14457:                                        d -= 2;
                   14458:                                } else if (*p == '.' && *--p == '/') {
                   14459:                                        while (p > clean && *--p != '/')
                   14460:                                                ;
                   14461:                                        d = p + 1;
                   14462:                                }
                   14463:                        }
                   14464:                }
                   14465:                if (!*s && !inslash && *(s - 1) != '/') {
                   14466:                        inslash = 1;
                   14467:                        s = slash;
                   14468:                }
                   14469:        }
                   14470: 
                   14471:        if (*(d - 1) == '/' && (d - 1) > clean)
                   14472:                d--;
                   14473:        *d = '\0';
                   14474: }
                   14475: ./pdksh/sh/sh.h   644    653   1762       16566  5302634513  10635 0ustar  hlu/*
                   14476:  * Public Domain Bourne/Korn shell
                   14477:  */
                   14478: 
                   14479: /* $Id: sh.h,v 1.5 1992/08/12 14:15:48 sjg Exp $ */
                   14480: 
                   14481: #include "config.h"
                   14482: 
                   14483: /* some useful #defines */
                   14484: #ifdef EXTERN
                   14485: # define _I_(i) = i
                   14486: #else
                   14487: # define _I_(i)
                   14488: # define EXTERN extern
                   14489: # define EXTERN_DEFINED
                   14490: #endif
                   14491: 
                   14492: #ifndef SHELL
                   14493: #define        SHELL   "/bin/sh"       /* shell to exec scripts */
                   14494: #endif
                   14495: 
                   14496: #ifdef _BSD
                   14497: #define memmove(dst, src, n)   bcopy((src), (dst), (n))
                   14498: #endif
                   14499: 
                   14500: /* some people object to this use of __STDC__ */
                   14501: #ifdef __STDC__
                   14502: #define        ARGS(args)      args    /* prototype declaration */
                   14503: #else
                   14504: #define        ARGS(args)      ()      /* K&R declaration */
                   14505: #ifdef VOID
                   14506: #define        void    VOID
                   14507: #endif
                   14508: #define        const   
                   14509: #define        volatile 
                   14510: #endif
                   14511: 
                   14512: #ifdef _ULTRIX                 /* Ultrix 2.x gets dup2 wrong */
                   14513: int dup2 ARGS ((int, int));
                   14514: /* assumes we don't want dup2 return value */
                   14515: #define        dup2(ofd, nfd) \
                   14516:                (void) ((dup2)(ofd, nfd), fcntl(nfd, F_SETFD, 0))
                   14517: #endif
                   14518: 
                   14519: #if defined(EMACS) || defined(VI)
                   14520: #define        EDIT
                   14521: #endif
                   14522: 
                   14523: typedef int bool_t;
                   14524: #define        FALSE   0
                   14525: #define        TRUE    1
                   14526: 
                   14527: #define        sizeofN(type, n) (sizeof(type) * (n))
                   14528: #define        BIT(i)  (1<<(i))        /* define bit in flag */
                   14529: 
                   14530: #define        NUFILE  10              /* Number of user-accessible files */
                   14531: #define        FDBASE  10              /* First file usable by Shell */
                   14532: 
                   14533: /* you're not going to run setuid shell scripts, are you? */
                   14534: #define        eaccess(path, mode)     access(path, mode)
                   14535: 
                   14536: #define        MAGIC   (char)0x80      /* prefix for ~*?[ during expand */
                   14537: #define        NOT     '!'     /* might use ^ */
                   14538: 
                   14539: #define        LINE    256             /* input line size */
                   14540: #define        PATH    256             /* pathname size */
                   14541: 
                   14542: EXTERN int     kshpid;         /* $$, shell pid */
                   14543: EXTERN int     exstat;         /* exit status */
                   14544: EXTERN int     async;          /* $!, last &'d pid */
                   14545: EXTERN volatile int sigchld_caught;    /* count of dead children */
                   14546: 
                   14547: 
                   14548: /*
                   14549:  * Area-based allocation built on malloc/free
                   14550:  */
                   14551: 
                   14552: typedef struct Area {
                   14553:        struct Block *free;     /* free list */
                   14554: } Area;
                   14555: 
                   14556: extern Area    aperm;          /* permanent object space */
                   14557: #define        APERM   &aperm
                   14558: #define        ATEMP   &e.area
                   14559: 
                   14560: /*
                   14561:  * parsing & execution environment
                   14562:  */
                   14563: EXTERN struct  env {
                   14564:        int     type;                   /* enviroment type - see below */
                   14565:        Area    area;                   /* temporary allocation area */
                   14566:        struct  block *loc;             /* local variables and functions */
                   14567:        short  *savefd;                 /* original redirected fd's */
                   14568:        struct  env *oenv;              /* link to previous enviroment */
                   14569:        jmp_buf jbuf;                   /* long jump back to env creator */
                   14570:        int     interactive;            /* fd's 0,1,2 are tty */
                   14571:        struct temp *temps;             /* temp files */
                   14572: } e;
                   14573: 
                   14574: #define        E_NONE  0               /* dummy enviroment */
                   14575: #define        E_PARSE 1               /* parsing command # */
                   14576: #define        E_EXEC  2               /* executing command tree */
                   14577: #define        E_LOOP  3               /* executing for/while # */
                   14578: #define        E_TCOM  5               /* executing simple command */
                   14579: #define        E_FUNC  6               /* executing function */
                   14580: #define        E_ERRH  7               /* general error handler # */
                   14581: /* # indicates env has valid jbuf */
                   14582: 
                   14583: /*
                   14584:  * flags
                   14585:  */
                   14586: #define        FEXPORT FLAG('a')       /* -a: allexport */
                   14587: #define        FERREXIT FLAG('e')      /* -e: errexit (quit on error) */
                   14588: #define        FBGNICE 29              /* bgnice */
                   14589: #define        FEMACS 30               /* emacs command editing */
                   14590: #define        FIGNEOF 27              /* ignoreeof (eof does not exit) */
                   14591: #define        FHASHALL FLAG('h')      /* -h: trackall, hashall */
                   14592: #define        FTALKING FLAG('i')      /* -i: interactive (talking type wireless) */
                   14593: #define        FKEYWORD FLAG('k')      /* -k: keyword (name=value anywhere) */
                   14594: #define        FMARKDIRS 28            /* markdirs */
                   14595: #define        FMONITOR FLAG('m')      /* -m: monitor */
                   14596: #define        FNOEXEC FLAG('n')       /* -n: noexec */
                   14597: #define        FNOGLOB FLAG('f')       /* -f: noglob */
                   14598: #define        FPRIVILEGED FLAG('p')   /* -p: privileged */
                   14599: #define        FSTDIN  FLAG('s')       /* -s (invocation): parse stdin */
                   14600: #define        FNOUNSET FLAG('u')      /* -u: nounset (unset vars is error) */
                   14601: #define        FVERBOSE FLAG('v')      /* -v: verbose (echo input) */
                   14602: #define        FVI 31                  /* vi command editing */
                   14603: #define        FXTRACE FLAG('x')       /* -x: (execute) xtrace */
                   14604: 
                   14605: #define        FLAG(c) (1 + c - 'a')   /* map char to flags index */
                   14606: #define        FLAGS   32
                   14607: EXTERN char flag [FLAGS];
                   14608: int    option ARGS((const char *name));
                   14609: char   *getoptions ARGS((void));
                   14610: void   printoptions ARGS((void));
                   14611: 
                   14612: extern char    null [];        /* null value for variable */
                   14613: 
                   14614: /*
                   14615:  * other functions
                   14616:  */
                   14617: char * substitute ARGS((char const *, int));
                   14618: char   *search();
                   14619: struct tbl *findcom();
                   14620: char   *strsave ARGS((char *, Area *));
                   14621: char   *ulton ARGS((unsigned long n, int base));
                   14622: int    xstrcmp();
                   14623: void   qsortp ARGS((void **base, size_t n, int (*compare)(void *, void *)));
                   14624: long   evaluate ARGS((const char *expr));
                   14625: void   resetopts();
                   14626: void   histsave();
                   14627: void   histlist();
                   14628: int    pr_menu ARGS((char **, int));
                   14629: 
                   14630: void   j_init ARGS((void));
                   14631: void   j_exit ARGS((void));
                   14632: void   j_notify ARGS((void));
                   14633: void   j_kill ARGS((int job, int sig));
                   14634: #ifdef JOBS
                   14635: void   j_change ARGS((void));
                   14636: int    j_resume ARGS((int job, int bg));
                   14637: #endif
                   14638: 
                   14639: /*
                   14640:  * error handling
                   14641:  */
                   14642: void   leave();        /* abort shell (or fail in subshell) */
                   14643: 
                   14644: /*
                   14645:  * library functions
                   14646:  */
                   14647: typedef        void (*handler_t)();    /* signal handler */
                   14648: 
                   14649: /* temp/here files. the file is removed when the struct is freed */
                   14650: struct temp {
                   14651:        struct  temp * next;
                   14652:        char   *name;
                   14653: };
                   14654: struct temp *maketemp ARGS((Area *ap));
                   14655: 
                   14656: /*
                   14657:  * stdio and our IO routines
                   14658:  */
                   14659: 
                   14660: #ifdef BUFSIZ                  /* <stdio.h> included? */
                   14661: extern FILE *  shf [NUFILE];   /* map shell fd to FILE */
                   14662: #endif
                   14663: void   fopenshf();
                   14664: void   flushshf();
                   14665: 
                   14666: #undef stdin
                   14667: #undef stdout
                   14668: 
                   14669: #define        stdin   shf[0]          /* standard input */
                   14670: #define        stdout  shf[1]          /* standard output */
                   14671: #define        shlout  shf[2]          /* shell output */
                   14672: 
                   14673: int    shellf ARGS((const char *fmt, ...)); /* fprintf(shlout, ); */
                   14674: int    errorf ARGS((const char *fmt, ...)); /* fprintf(shlout, ); error(); */
                   14675: 
                   14676: /*
                   14677:  * IO control
                   14678:  */
                   14679: extern int ttyfd;              /* tty fd (original fd 0) */
                   14680: 
                   14681: int    savefd ARGS((int fd));  /* save user fd */
                   14682: void   restfd ARGS((int fd, int ofd));
                   14683: void   openpipe ARGS((int [2]));
                   14684: void   closepipe ARGS((int [2]));
                   14685: 
                   14686: /*
                   14687:  * trap handlers
                   14688:  */
                   14689: typedef struct trap {
                   14690:        int     signal;         /* signal number */
                   14691:        char   *name;           /* short name */
                   14692:        char   *mess;           /* descriptive name */
                   14693:        char   *trap;           /* trap command */
                   14694:        int     volatile set;   /* trap pending */
                   14695:        int     ourtrap;        /* not ignored (?) */
                   14696:        int     sig_dfl;        /* originally SIG_DFL */
                   14697: } Trap;
                   14698: 
                   14699: #ifndef        SIGKILL
                   14700: #include <signal.h>
                   14701: #endif /* SIGKILL */
                   14702: #ifdef NSIG
                   14703: #define        SIGNALS NSIG
                   14704: #else
                   14705: #ifdef _MINIX
                   14706: #define        SIGNALS (_NSIG+1)       /* _NSIG is # of signals used, excluding 0. */
                   14707: #else
                   14708: #define        SIGNALS 32
                   14709: #endif /* _MINIX */
                   14710: #endif /* NSIG */
                   14711: 
                   14712: #ifdef USE_SIGACT                      /* always use it? */
                   14713: #ifndef  SA_NOCLDSTOP
                   14714: # include "sigact.h"                   /* use sjg's fake sigaction() */
                   14715: #endif
                   14716: EXTERN struct sigaction Sigact, Sigact_dfl, Sigact_ign, Sigact_trap;
                   14717: #endif
                   14718: 
                   14719: EXTERN int volatile trap;      /* traps pending? */
                   14720: extern Trap    sigtraps[SIGNALS];
                   14721: Trap    *gettrap ARGS((char *)); /* search for struct trap by number or name */
                   14722: void   trapsig ARGS((int sig)); /* trap signal handler */
                   14723: 
                   14724: /*
                   14725:  * fast character classes
                   14726:  */
                   14727: #define        C_ALPHA 0x01            /* a-z_A-Z */
                   14728: #define        C_DIGIT 0x02            /* 0-9 */
                   14729: #define        C_LEX1  0x04            /* \0 \t\n|&;<>() */
                   14730: #define        C_VAR1  0x08            /* *@#!$-? */
                   14731: #define        C_SUBOP 0x40            /* "=-+?#%" */
                   14732: #define        C_IFS   0x80            /* $IFS */
                   14733: 
                   14734: extern char ctypes [];
                   14735: #if 0
                   14736: void   initctypes ARGS((void));
                   14737: void   setctypes ARGS((const char*, int type));
                   14738: #endif
                   14739: #define        ctype(c, t)     !!(ctypes[(unsigned char)(c)]&(t))
                   14740: #define        letter(c)       ctype(c, C_ALPHA)
                   14741: #define        digit(c)        ctype(c, C_DIGIT)
                   14742: #define        letnum(c)       ctype(c, C_ALPHA|C_DIGIT)
                   14743: 
                   14744: #include "table.h"
                   14745: #include "tree.h"
                   14746: #include "lex.h"
                   14747: #include "proto.h"
                   14748:   
                   14749: /*
                   14750:  * 91-07-06 <sjg@sun0>
                   14751:  * use my simple debug tracing... 
                   14752:  */
                   14753: #include "trace.h"
                   14754: 
                   14755: #ifdef linux
                   14756: #include <stdio.h>
                   14757: #else
                   14758: #ifndef fileno
                   14759: /* This is quite outrageous. H.J. */
                   14760: #define fileno(p)      ((p)->_file)
                   14761: #endif
                   14762: #endif
                   14763: 
                   14764: /* be sure not to interfere with anyone else's idea about EXTERN */
                   14765: #ifdef EXTERN_DEFINED
                   14766: # undef EXTERN_DEFINED
                   14767: # undef EXTERN
                   14768: #endif
                   14769: #undef _I_
                   14770: /*
                   14771:  * Local Variables:
                   14772:  * version-control:t
                   14773:  * comment-column:40
                   14774:  * End:
                   14775:  */
                   14776: ./pdksh/sh/table.c   644    653   1762        7360  5243743614  11264 0ustar  hlu#ifndef lint
                   14777: static char *RCSid = "$Id: table.c,v 1.2 1992/04/25 08:33:28 sjg Exp $";
                   14778: #endif
                   14779: 
                   14780: /*
                   14781:  * dynamic hashed associative table for commands and variables
                   14782:  */
                   14783: 
                   14784: #include "stdh.h"
                   14785: #include <errno.h>
                   14786: #include <setjmp.h>
                   14787: #include "sh.h"
                   14788: 
                   14789: #define        INIT_TBLS       8       /* initial table size (power of 2) */
                   14790: 
                   14791: static struct tstate {
                   14792:        int left;
                   14793:        struct tbl **next;
                   14794: } tstate;
                   14795: 
                   14796: static void     texpand     ARGS((struct table *tp, int nsize));
                   14797: static int      tnamecmp    ARGS((void *p1, void *p2));
                   14798: 
                   14799: 
                   14800: unsigned int
                   14801: hash(n)
                   14802:        register char * n;
                   14803: {
                   14804:        register unsigned int h = 0;
                   14805: 
                   14806:        while (*n != '\0')
                   14807:                h = 2*h + *n++;
                   14808:        return h * 32821;       /* scatter bits */
                   14809: }
                   14810: 
                   14811: #if 0
                   14812: phash(s) char *s; {
                   14813:        printf("%2d: %s\n", hash(s)%32, s);
                   14814: }
                   14815: #endif
                   14816: 
                   14817: void
                   14818: tinit(tp, ap)
                   14819:        register struct table *tp;
                   14820:        register Area *ap;
                   14821: {
                   14822:        tp->areap = ap;
                   14823:        tp->size = tp->free = 0;
                   14824:        tp->tbls = NULL;
                   14825: }
                   14826: 
                   14827: static void
                   14828: texpand(tp, nsize)
                   14829:        register struct table *tp;
                   14830:        int nsize;
                   14831: {
                   14832:        register int i;
                   14833:        register struct tbl *tblp, **p;
                   14834:        register struct tbl **ntblp, **otblp = tp->tbls;
                   14835:        int osize = tp->size;
                   14836: 
                   14837:        ntblp = (struct tbl**) alloc(sizeofN(struct tbl *, nsize), tp->areap);
                   14838:        for (i = 0; i < nsize; i++)
                   14839:                ntblp[i] = NULL;
                   14840:        tp->size = nsize;
                   14841:        tp->free = 8*nsize/10;  /* table can get 80% full */
                   14842:        tp->tbls = ntblp;
                   14843:        if (otblp == NULL)
                   14844:                return;
                   14845:        for (i = 0; i < osize; i++)
                   14846:                if ((tblp = otblp[i]) != NULL)
                   14847:                        if ((tblp->flag&DEFINED)) {
                   14848:                                for (p = &ntblp[hash(tblp->name) &
                   14849:                                                (tp->size-1)];
                   14850:                                     *p != NULL; p--)
                   14851:                                        if (p == ntblp) /* wrap */
                   14852:                                                p += tp->size;
                   14853:                                *p = tblp;
                   14854:                                tp->free--;
                   14855:                        } else {
                   14856:                                afree((void*)tblp, tp->areap);
                   14857:                        }
                   14858:        afree((void*)otblp, tp->areap);
                   14859: }
                   14860: 
                   14861: struct tbl *
                   14862: tsearch(tp, n, h)
                   14863:        register struct table *tp;      /* table */
                   14864:        register char *n;               /* name to enter */
                   14865:        unsigned int h;                 /* hash(n) */
                   14866: {
                   14867:        register struct tbl **pp, *p;
                   14868: 
                   14869:        if (tp->size == 0)
                   14870:                return NULL;
                   14871: 
                   14872:        /* search for name in hashed table */
                   14873:        for (pp = &tp->tbls[h & (tp->size-1)]; (p = *pp) != NULL; pp--) {
                   14874:                if (*p->name == *n && strcmp(p->name, n) == 0
                   14875:                    && (p->flag&DEFINED))
                   14876:                        return p;
                   14877:                if (pp == tp->tbls) /* wrap */
                   14878:                        pp += tp->size;
                   14879:        }
                   14880: 
                   14881:        return NULL;
                   14882: }
                   14883: 
                   14884: struct tbl *
                   14885: tenter(tp, n, h)
                   14886:        register struct table *tp;      /* table */
                   14887:        register char *n;               /* name to enter */
                   14888:        unsigned int h;                 /* hash(n) */
                   14889: {
                   14890:        register struct tbl **pp, *p;
                   14891:        register char *cp;
                   14892: 
                   14893:        if (tp->size == 0)
                   14894:                texpand(tp, INIT_TBLS);
                   14895:   Search:
                   14896:        /* search for name in hashed table */
                   14897:        for (pp = &tp->tbls[h & (tp->size-1)]; (p = *pp) != NULL; pp--) {
                   14898:                if (*p->name == *n && strcmp(p->name, n) == 0)
                   14899:                        return p;       /* found */
                   14900:                if (pp == tp->tbls) /* wrap */
                   14901:                        pp += tp->size;
                   14902:        }
                   14903: 
                   14904:        if (tp->free <= 0) {    /* too full */
                   14905:                texpand(tp, 2*tp->size);
                   14906:                goto Search;
                   14907:        }
                   14908: 
                   14909:        /* create new tbl entry */
                   14910:        for (cp = n; *cp != '\0'; cp++)
                   14911:                ;
                   14912:        p = (struct tbl *) alloc(offsetof(struct tbl, name[(cp-n)+1]), tp->areap);
                   14913:        p->flag = 0;
                   14914:        p->type = 0;
                   14915:        for (cp = p->name; *n != '\0';)
                   14916:                *cp++ = *n++;
                   14917:        *cp = '\0';
                   14918: 
                   14919:        /* enter in tp->tbls */
                   14920:        tp->free--;
                   14921:        *pp = p;
                   14922:        return p;
                   14923: }
                   14924: 
                   14925: void
                   14926: tdelete(p)
                   14927:        register struct tbl *p;
                   14928: {
                   14929:        p->flag = 0;
                   14930: }
                   14931: 
                   14932: void
                   14933: twalk(tp)
                   14934:        register struct table *tp;
                   14935: {
                   14936:        tstate.left = tp->size;
                   14937:        tstate.next = tp->tbls;
                   14938: }
                   14939: 
                   14940: struct tbl *
                   14941: tnext()
                   14942: {
                   14943:        while (--tstate.left >= 0) {
                   14944:                struct tbl *p = *tstate.next++;
                   14945:                if (p != NULL && (p->flag&DEFINED))
                   14946:                        return p;
                   14947:        }
                   14948:        return NULL;
                   14949: }
                   14950: 
                   14951: static int
                   14952: tnamecmp(p1, p2)
                   14953:        void *p1, *p2;
                   14954: {
                   14955:        return strcmp(((struct tbl *)p1)->name, ((struct tbl *)p2)->name);
                   14956: }
                   14957: 
                   14958: struct tbl **
                   14959: tsort(tp)
                   14960:        register struct table *tp;
                   14961: {
                   14962:        register int i;
                   14963:        register struct tbl **p, **sp, **dp;
                   14964: 
                   14965:        p = (struct tbl **)alloc(sizeofN(struct tbl *, tp->size+1), ATEMP);
                   14966:        sp = tp->tbls;          /* source */
                   14967:        dp = p;                 /* dest */
                   14968:        for (i = 0; i < tp->size; i++)
                   14969:                if ((*dp = *sp++) != NULL && ((*dp)->flag&DEFINED))
                   14970:                        dp++;
                   14971:        i = dp - p;
                   14972:        qsortp((void**)p, (size_t)i, tnamecmp);
                   14973:        p[i] = NULL;
                   14974:        return p;
                   14975: }
                   14976: 
                   14977: ./pdksh/sh/Makefile   644    653   1762       12705  5303002252  11467 0ustar  hlu# PD Bourne/Korn Shell
                   14978: # $Id: Makefile,v 1.3 1992/08/10 12:02:18 sjg Exp $
                   14979: 
                   14980: SHELL = /bin/sh
                   14981: MAKE  = make
                   14982: 
                   14983: LN    = ln -s
                   14984: 
                   14985: # You _can_ build this shell without the ../std tree if your
                   14986: # system provides a sufficiently POSIX environment, or if your
                   14987: # BSD system is a Sun or close.  If not try ../std.
                   14988: 
                   14989: # gcc is good value on most mc68k's and sun386's if nothing else.
                   14990: # if you don't have gcc cc should do
                   14991: # CC=gcc -pipe
                   14992: CC=gcc -pipe 
                   14993: CC=/usr/local/bin/gcc
                   14994: 
                   14995: # The following are the defintions used (or thereabouts) 
                   14996: # to build ksh without ../std
                   14997: #
                   14998: # sun386 SunOS 4.0.2, sun3 SunOS 4.0.3
                   14999: # CONFIG=-D_BSD
                   15000: # XOPTS=-DNOSTDHDRS
                   15001: # copy these from ../std/stdc or ensure they are in libstdc.a
                   15002: # XOBJS = memmove.o strstr.o 
                   15003: #
                   15004: # sun3  SunOS 4.1.1
                   15005: # CONFIG=-D_BSD
                   15006: # XOPTS=-DNOSTDHDRS
                   15007: # copy these from ../std/stdc or ensure they are in libstdc.a
                   15008: # XOBJS = memmove.o
                   15009: #
                   15010: # sun4c (sparc) SunOS 4.1.1
                   15011: # CC=cc -pipe  # don't use gcc
                   15012: # CONFIG=-D_BSD
                   15013: # XOPTS=-DNOSTDHDRS
                   15014: # copy these from ../std/stdc or ensure they are in libstdc.a
                   15015: # XOBJS = memmove.o
                   15016: #
                   15017: # Bull DPX/2 B.O.S. 2.00.45
                   15018: # CC=gcc -ansi
                   15019: # CONFIG=-D_POSIX_SOURCE
                   15020: # XOPTS=
                   15021: # XOBJS=
                   15022: #
                   15023: # Minix-386 1.5.10 with estdio
                   15024: # CONFIG= -D_BSD -D_MINIX -D_POSIX_SOURCE
                   15025: # XOPTS=
                   15026: # XOBJS=
                   15027: #
                   15028: # BSD/386
                   15029: # CONFIG= -D_BSDI -D_POSIX_TERM -D_POSIX_SOURCE
                   15030: # XOPTS=
                   15031: # XOBJS=
                   15032: 
                   15033: #CONFIG= -D_SYSV
                   15034: #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
                   15035: CONFIG= -D_BSD -DCOMPLEX_HISTORY
                   15036: 
                   15037: 
                   15038: STD=../std
                   15039: INCL=$(STD)/h
                   15040: XINCL=-I$(INCL)
                   15041: LDOPTS=-L$(STD)
                   15042: XOBJS=
                   15043: 
                   15044: # use -O if you trust it :-)
                   15045: DBG=-g -O
                   15046: DBG=-O
                   15047: CFLAGS = $(DBG) $(CONFIG) $(XINCL) $(XOPTS)
                   15048: 
                   15049: LDFLAGS = $(DBG) $(LDOPTS)
                   15050: 
                   15051: #COMPATLIBS = -lstdc -lposix
                   15052: #XLIBS = -lc_s
                   15053: #XLIBS = -ldirent
                   15054: LDLIBS = $(COMPATLIBS) $(XLIBS)
                   15055: 
                   15056: HDRS = sh.h table.h expand.h lex.h tree.h tty.h trace.h
                   15057: SRCS1 =        version.c main.c misc.c trap.c alloc.c io.c \
                   15058:        syn.c lex.c edit.c emacs.c vi.c history.c tree.c 
                   15059: SRCS2 =        exec.c jobs.c \
                   15060:        c_sh.c c_ksh.c c_test.c getopts.c do_ulimit.c \
                   15061:        var.c table.c eval.c expr.c mail.c sigact.c trace.c
                   15062: SRCS = Makefile $(HDRS) $(SRCS1) $(SRCS2) 
                   15063: 
                   15064: OBJS = version.o main.o misc.o \
                   15065:        syn.o lex.o edit.o emacs.o vi.o tree.o \
                   15066:        exec.o jobs.o trap.o \
                   15067:        c_sh.o c_ksh.o c_test.o \
                   15068:        do_ulimit.o getopts.o expr.o history.o \
                   15069:        var.o table.o alloc.o io.o eval.o mail.o sigact.o trace.o $(XOBJS)
                   15070: 
                   15071: ksh: $(OBJS) 
                   15072:        $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
                   15073: 
                   15074: clean:
                   15075:        rm -f *.o *.out core
                   15076: 
                   15077: clobber: clean
                   15078:        rm -f ksh
                   15079: 
                   15080: link:
                   15081:        ($(SHELL) ../std/mklinks ../std/h stdh.h)
                   15082:        
                   15083: 
                   15084: depend:
                   15085:        makedepend $(CFLAGS) $(SRCS1) $(SRCS2)
                   15086: 
                   15087: install:
                   15088:        @echo "Try:"
                   15089:        @echo "cp ksh /bin"
                   15090:        @echo "strip /bin/ksh"
                   15091:        @echo "chmod 555 /bin/ksh"
                   15092: 
                   15093: .c.s:
                   15094:        $(CC) $(CFLAGS) -S -o $@ $<
                   15095: 
                   15096: asms: $(OBJS:.o=.s)
                   15097: 
                   15098: 
                   15099: # DO NOT DELETE THIS LINE -- make depend depends on it.
                   15100: # If this runs make out of memory, delete /usr/include lines.
                   15101: alloc.o: alloc.c
                   15102: alloc.o: config.h
                   15103: alloc.o: sh.h
                   15104: alloc.o: stdh.h
                   15105: alloc.o: trace.h
                   15106: c_ksh.o: c_ksh.c
                   15107: c_ksh.o: config.h
                   15108: c_ksh.o: sh.h
                   15109: c_ksh.o: stdh.h
                   15110: c_ksh.o: table.h
                   15111: c_ksh.o: trace.h
                   15112: c_sh.o: c_sh.c
                   15113: c_sh.o: config.h
                   15114: c_sh.o: lex.h
                   15115: c_sh.o: sh.h
                   15116: c_sh.o: stdh.h
                   15117: c_sh.o: table.h
                   15118: c_sh.o: trace.h
                   15119: c_sh.o: tree.h
                   15120: c_test.o: c_test.c
                   15121: c_test.o: config.h
                   15122: c_test.o: sh.h
                   15123: c_test.o: stdh.h
                   15124: c_test.o: trace.h
                   15125: edit.o: config.h
                   15126: edit.o: edit.c
                   15127: edit.o: edit.h
                   15128: edit.o: lex.h
                   15129: edit.o: sh.h
                   15130: edit.o: stdh.h
                   15131: edit.o: trace.h
                   15132: edit.o: tty.h
                   15133: emacs.o: config.h
                   15134: emacs.o: edit.h
                   15135: emacs.o: emacs.c
                   15136: emacs.o: expand.h
                   15137: emacs.o: lex.h
                   15138: emacs.o: sh.h
                   15139: emacs.o: stdh.h
                   15140: emacs.o: table.h
                   15141: emacs.o: trace.h
                   15142: emacs.o: tree.h
                   15143: eval.o: config.h
                   15144: eval.o: eval.c
                   15145: eval.o: expand.h
                   15146: eval.o: lex.h
                   15147: eval.o: sh.h
                   15148: eval.o: stdh.h
                   15149: eval.o: table.h
                   15150: eval.o: trace.h
                   15151: eval.o: tree.h
                   15152: exec.o: config.h
                   15153: exec.o: exec.c
                   15154: exec.o: lex.h
                   15155: exec.o: sh.h
                   15156: exec.o: stdh.h
                   15157: exec.o: table.h
                   15158: exec.o: trace.h
                   15159: exec.o: tree.h
                   15160: expr.o: config.h
                   15161: expr.o: expr.c
                   15162: expr.o: sh.h
                   15163: expr.o: stdh.h
                   15164: expr.o: table.h
                   15165: expr.o: trace.h
                   15166: getopts.o: config.h
                   15167: getopts.o: getopts.c
                   15168: getopts.o: sh.h
                   15169: getopts.o: stdh.h
                   15170: getopts.o: table.h
                   15171: getopts.o: trace.h
                   15172: history.o: config.h
                   15173: history.o: history.c
                   15174: history.o: lex.h
                   15175: history.o: sh.h
                   15176: history.o: stdh.h
                   15177: history.o: trace.h
                   15178: io.o: config.h
                   15179: io.o: io.c
                   15180: io.o: sh.h
                   15181: io.o: stdh.h
                   15182: io.o: trace.h
                   15183: jobs.o: config.h
                   15184: jobs.o: jobs.c
                   15185: jobs.o: sh.h
                   15186: jobs.o: stdh.h
                   15187: jobs.o: trace.h
                   15188: jobs.o: tree.h
                   15189: lex.o: config.h
                   15190: lex.o: expand.h
                   15191: lex.o: lex.c
                   15192: lex.o: lex.h
                   15193: lex.o: sh.h
                   15194: lex.o: stdh.h
                   15195: lex.o: table.h
                   15196: lex.o: trace.h
                   15197: lex.o: tree.h
                   15198: mail.o: config.h
                   15199: mail.o: mail.c
                   15200: mail.o: sh.h
                   15201: mail.o: stdh.h
                   15202: mail.o: table.h
                   15203: mail.o: trace.h
                   15204: main.o: config.h
                   15205: main.o: lex.h
                   15206: main.o: main.c
                   15207: main.o: sh.h
                   15208: main.o: stdh.h
                   15209: main.o: table.h
                   15210: main.o: trace.h
                   15211: main.o: tree.h
                   15212: memmove.o: memmove.c
                   15213: memmove.o: stdh.h
                   15214: misc.o: config.h
                   15215: misc.o: expand.h
                   15216: misc.o: misc.c
                   15217: misc.o: sh.h
                   15218: misc.o: stdh.h
                   15219: misc.o: trace.h
                   15220: strstr.o: stdh.h
                   15221: strstr.o: strstr.c
                   15222: syn.o: config.h
                   15223: syn.o: expand.h
                   15224: syn.o: lex.h
                   15225: syn.o: sh.h
                   15226: syn.o: stdh.h
                   15227: syn.o: syn.c
                   15228: syn.o: table.h
                   15229: syn.o: trace.h
                   15230: syn.o: tree.h
                   15231: sigact.o: sigact.h sigact.c
                   15232: table.o: config.h
                   15233: table.o: sh.h
                   15234: table.o: stdh.h
                   15235: table.o: table.c
                   15236: table.o: table.h
                   15237: table.o: trace.h
                   15238: times.o: times.c
                   15239: trace.o: trace.c
                   15240: trap.o: config.h
                   15241: trap.o: sh.h
                   15242: trap.o: stdh.h
                   15243: trap.o: trace.h
                   15244: trap.o: trap.c
                   15245: tree.o: config.h
                   15246: tree.o: sh.h
                   15247: tree.o: stdh.h
                   15248: tree.o: trace.h
                   15249: tree.o: tree.c
                   15250: tree.o: tree.h
                   15251: do_ulimit.o: config.h
                   15252: do_ulimit.o: sh.h
                   15253: do_ulimit.o: stdh.h
                   15254: do_ulimit.o: trace.h
                   15255: do_ulimit.o: do_ulimit.c
                   15256: var.o: config.h
                   15257: var.o: expand.h
                   15258: var.o: sh.h
                   15259: var.o: stdh.h
                   15260: var.o: table.h
                   15261: var.o: trace.h
                   15262: var.o: var.c
                   15263: version.o: config.h
                   15264: version.o: sh.h
                   15265: version.o: stdh.h
                   15266: version.o: trace.h
                   15267: version.o: version.c
                   15268: vi.o: config.h
                   15269: vi.o: edit.h
                   15270: vi.o: expand.h
                   15271: vi.o: lex.h
                   15272: vi.o: sh.h
                   15273: vi.o: stdh.h
                   15274: vi.o: table.h
                   15275: vi.o: trace.h
                   15276: vi.o: tree.h
                   15277: vi.o: vi.c
                   15278: # WARNING: Put nothing here or make depend will gobble it up!
                   15279: ./pdksh/sh/ReadMe   644    653   1762        3104  5243742756  11107 0ustar  hlu            Public Domain KornShell
                   15280: 
                   15281:        Quick installation notes for PD KornShell
                   15282: 
                   15283: PD KornShell can be installed on 4.2+ BSD systems, System V, and
                   15284: POSIX-compatable systems.  The makefiles all define _BSD, change
                   15285: this to _SYSV, or _POSIX.  The makefiles also contain CC=gcc,
                   15286: delete this if you don't have GNU C.  The ksh makefile also
                   15287: contains some options, including JOBS (BSD/POSIX job control)
                   15288: and EDIT (emacs command editing).
                   15289: 
                   15290: PD KornShell assumes you have standard C (ANSI) and POSIX header
                   15291: files and functions. Since you probably don't, they are provided
                   15292: in the "std" directory.
                   15293: 
                   15294: The Alpha test version will probably come as two tar files.
                   15295: std.tar contains standard C and POSIX emulation and must be
                   15296: extracted into a directory called std.  ksh.tar contains the ksh
                   15297: source and should be extracted into a directory called src or
                   15298: ksh.
                   15299: 
                   15300: See std/ReadMe and install it. Only then can you make ksh in the
                   15301: "src" directory.
                   15302: 
                   15303: To clear up questions about the origin of this shell, this shell
                   15304: is NOT based on the "Minix shell".  It is based on Charles
                   15305: Forsyth's public domain V7 shell, which he later contributed to
                   15306: Minix.
                   15307: 
                   15308: I have permission directly from Charles Forsyth to use his shell.
                   15309: 
                   15310:        Eric Gisin, [email protected] (or Waterloo.EDU)
                   15311: 
                   15312:        Things to do
                   15313: - add sxt-based job control (see Brown's contribution on the Usenix 87 tape).
                   15314: - add arrays and variable attributes.
                   15315: - add MAILPATH and CDPATH.
                   15316: - add vi editing mode (apparently someone has a PD version).
                   15317: - add new features described in Korn's book.
                   15318: 
                   15319:        Machines ported to
                   15320: VAX, 68000, 80386
                   15321: 
                   15322:        OS's ported to
                   15323: BSD 4.2, BSD 4.3 (with and without YP and NFS
                   15324: Sys V.3
                   15325: ./pdksh/sh/alloc.h   644    653   1762         172  5243743566  11254 0ustar  hlu/*
                   15326:  * area-based allocation built on malloc/free
                   15327:  */
                   15328: 
                   15329: typedef struct Area {
                   15330:        struct Block *free;     /* free list */
                   15331: } Area;
                   15332: 
                   15333: ./pdksh/sh/edit.h   644    653   1762        4134  5243743674  11131 0ustar  hlu/* NAME:
                   15334:  *      edit.h - globals for edit modes
                   15335:  *
                   15336:  * DESCRIPTION:
                   15337:  *      This header defines various global edit objects.
                   15338:  *
                   15339:  * SEE ALSO:
                   15340:  *      
                   15341:  *
                   15342:  * RCSid:
                   15343:  *      $Id: edit.h,v 1.4 1992/08/12 14:15:25 sjg Exp $
                   15344:  *
                   15345:  */
                   15346: 
                   15347: /* some useful #defines */
                   15348: #ifdef EXTERN
                   15349: # define _I_(i) = i
                   15350: #else
                   15351: # define _I_(i)
                   15352: # define EXTERN extern
                   15353: # define EXTERN_DEFINED
                   15354: #endif
                   15355: 
                   15356: #define        BEL             0x07
                   15357: 
                   15358: /*
                   15359:  * The following are used for my horizontal scrolling stuff
                   15360:  */
                   15361: EXTERN char   *xbuf;           /* beg input buffer */
                   15362: EXTERN char   *xend;           /* end input buffer */
                   15363: EXTERN char    *xcp;           /* current position */
                   15364: EXTERN char    *xep;           /* current end */
                   15365: EXTERN char    *xbp;           /* start of visible portion of input buffer */
                   15366: EXTERN char    *xlp;           /* last char visible on screen */
                   15367: EXTERN int     x_adj_ok;
                   15368: /*
                   15369:  * we use x_adj_done so that functions can tell 
                   15370:  * whether x_adjust() has been called while they are active.
                   15371:  */
                   15372: EXTERN int     x_adj_done;
                   15373: 
                   15374: EXTERN int     x_cols _I_(80); /* default to 80 cols */
                   15375: EXTERN int     x_col;
                   15376: EXTERN int     x_displen;
                   15377: EXTERN int     x_arg;          /* general purpose arg */
                   15378: 
                   15379: EXTERN int     x_do_init;              /* set up tty modes */
                   15380: EXTERN int     ed_erase, ed_kill, ed_werase, ed_intr, ed_quit;
                   15381: 
                   15382: #ifdef DEBUG
                   15383: # define _D_(x) x
                   15384: #else
                   15385: # define _D_(x)
                   15386: #endif
                   15387: 
                   15388: /****  edit.c  ****/
                   15389: int             x_read      ARGS((int fd, char *buf, size_t len));
                   15390: int             x_getc      ARGS((void));
                   15391: void            x_flush     ARGS((void));
                   15392: void            x_adjust    ARGS((void));
                   15393: void            x_putc      ARGS((int c));
                   15394: int             x_debug_info ARGS((void));
                   15395: void            x_puts      ARGS((char *s));
                   15396: void            x_init      ARGS((void));
                   15397: bool_t          x_mode      ARGS((bool_t onoff));
                   15398: bool_t          x_mode      ARGS((bool_t onoff));
                   15399: int             promptlen   ARGS((char *cp));
                   15400: 
                   15401: /****  emacs.c  ****/
                   15402: void            x_redraw    ARGS((int limit));
                   15403: char*          x_lastcp    ARGS((void));
                   15404: EXTERN int xlp_valid _I_(0);
                   15405:   
                   15406: /* This lot goes at the END */
                   15407: /* be sure not to interfere with anyone else's idea about EXTERN */
                   15408: #ifdef EXTERN_DEFINED
                   15409: # undef EXTERN_DEFINED
                   15410: # undef EXTERN
                   15411: #endif
                   15412: #undef _I_
                   15413: /*
                   15414:  * Local Variables:
                   15415:  * version-control:t
                   15416:  * comment-column:40
                   15417:  * End:
                   15418:  */
                   15419: ./pdksh/sh/expand.h   644    653   1762        4250  5243743574  11461 0ustar  hlu/*
                   15420:  * Expanding strings
                   15421:  */
                   15422: 
                   15423: #if 0                          /* Usage */
                   15424:        XString xs;
                   15425:        char *xp;
                   15426: 
                   15427:        Xinit(xs, xp, 128);     /* allocate initial string */
                   15428:        while ((c = generate()) {
                   15429:                Xcheck(xs, xp); /* expand string if neccessary */
                   15430:                Xput(xs, xp, c); /* add character */
                   15431:        }
                   15432:        return Xclose(xs, xp);  /* resize string */
                   15433: #endif
                   15434: 
                   15435: typedef struct XString {
                   15436:        char   *end, *beg;      /* end, begin of string */
                   15437: #if 1
                   15438:        char   *oth, *old;      /* togo, adjust */
                   15439: #endif
                   15440:        size_t  len;            /* length */
                   15441: } XString;
                   15442: 
                   15443: typedef char * XStringP;
                   15444: 
                   15445: /* initialize expandable string */
                   15446: #define        Xinit(xs, xp, length) { \
                   15447:                        (xs).len = length; \
                   15448:                        (xs).beg = alloc((xs).len + 8, ATEMP); \
                   15449:                        (xs).end = (xs).beg + (xs).len; \
                   15450:                        xp = (xs).beg; \
                   15451:                }
                   15452: 
                   15453: /* stuff char into string */
                   15454: #define        Xput(xs, xp, c) *xp++ = (c)
                   15455: 
                   15456: /* check for overflow, expand string */
                   15457: #define        Xcheck(xs, xp) if (xp >= (xs).end) { \
                   15458:                        char *old_beg = (xs).beg; \
                   15459:                        (xs).len += (xs).len; /* double size */ \
                   15460:                        (xs).beg = aresize((xs).beg, (xs).len + 8, ATEMP); \
                   15461:                        (xs).end = (xs).beg + (xs).len; \
                   15462:                        xp = (xs).beg + (xp - old_beg); /* adjust pointer */ \
                   15463:                }
                   15464: 
                   15465: /* free string */
                   15466: #define        Xfree(xs, xp)   afree((void*) (xs).beg, ATEMP)
                   15467: 
                   15468: /* close, return string */
                   15469: #define        Xclose(xs, xp)  (char*) aresize((void*)(xs).beg, \
                   15470:                                        (size_t)(xp - (xs).beg), ATEMP)
                   15471: /* begin of string */
                   15472: #define        Xstring(xs, xp) ((xs).beg)
                   15473: 
                   15474: #define        Xsavepos(xs, xp) (xp - (xs).beg)
                   15475: #define        Xrestpos(xs, xp, n) ((xs).beg + (n))
                   15476: 
                   15477: /*
                   15478:  * expandable vector of generic pointers
                   15479:  */
                   15480: 
                   15481: typedef struct XPtrV {
                   15482:        void  **cur;            /* next avail pointer */
                   15483:        void  **beg, **end;     /* begin, end of vector */
                   15484: } XPtrV;
                   15485: 
                   15486: #define        XPinit(x, n) { \
                   15487:                        register void **vp; \
                   15488:                        vp = (void**) alloc(sizeofN(void*, n), ATEMP); \
                   15489:                        (x).cur = (x).beg = vp; \
                   15490:                        (x).end = vp + n; \
                   15491:                        }
                   15492: 
                   15493: #define        XPput(x, p) { \
                   15494:                        if ((x).cur >= (x).end) { \
                   15495:                                int n = XPsize(x); \
                   15496:                                (x).beg = (void**) aresize((void*) (x).beg, \
                   15497:                                                   sizeofN(void*, n*2), ATEMP); \
                   15498:                                (x).cur = (x).beg + n; \
                   15499:                                (x).end = (x).cur + n; \
                   15500:                        } \
                   15501:                        *(x).cur++ = (p); \
                   15502:                        }
                   15503: 
                   15504: #define        XPptrv(x)       ((x).beg)
                   15505: #define        XPsize(x)       ((x).cur - (x).beg)
                   15506: 
                   15507: #define        XPclose(x)      (void**) aresize((void*)(x).beg, \
                   15508:                                         sizeofN(void*, XPsize(x)), ATEMP)
                   15509: 
                   15510: #define        XPfree(x)       afree((void*) (x).beg, ATEMP)
                   15511: 
                   15512: ./pdksh/sh/getopts.c   644    653   1762        6760  5243743656  11673 0ustar  hlu/*
                   15513:  * Reimplementation of SysVr3 sh builtin command "getopts" for S5R2 shell.
                   15514:  *
                   15515:  * created by Arnold Robbins
                   15516:  * modified by Doug Gwyn
                   15517:  * modified for PD ksh by Eric Gisin
                   15518:  */
                   15519: 
                   15520: #ifndef lint
                   15521: static char *RCSid = "$Id: getopts.c,v 1.3 1992/08/10 12:02:41 sjg Exp $";
                   15522: #endif
                   15523: 
                   15524: #include "stdh.h"
                   15525: #include <errno.h>
                   15526: #include <setjmp.h>
                   15527: #include "sh.h"
                   15528: 
                   15529: #ifdef _BSDI
                   15530: /* internal getopt conflicts with system getopt prototype */
                   15531: # define getopt        local_getopt
                   15532: #endif
                   15533: 
                   15534: /*
                   15535:  * The following is derived from getopt() source placed into the public
                   15536:  * domain by AT&T (the only time they're known to have done that).
                   15537:  *
                   15538:  * It has been modified somewhat to fit into the context of the shell.
                   15539:  *
                   15540:  * -D"FASCIST" if you really want to strictly enforce ALL the
                   15541:  * Command Syntax Standard rules (not recommended).
                   15542:  */
                   15543: 
                   15544: #define GETOPTEOF      (-1)
                   15545: #define ERR(S, C)      shellf("%s%c\n", (S), (C))
                   15546: 
                   15547: static int     optind;
                   15548: static char    *optarg;
                   15549: static int     sp;
                   15550: 
                   15551: static int
                   15552: getopt(argc, argv, opts)
                   15553:        int argc;
                   15554:        register char **argv, *opts;
                   15555: {
                   15556:        register int c;
                   15557:        register char *cp;
                   15558: 
                   15559:        if (sp == 1)
                   15560:                if (optind >= argc ||
                   15561:                   argv[optind][0] != '-' || argv[optind][1] == '\0')
                   15562:                        return(GETOPTEOF);
                   15563:                else if (strcmp(argv[optind], "--") == 0) {
                   15564:                        optind++;
                   15565:                        return(GETOPTEOF);
                   15566:                }
                   15567:        c = argv[optind][sp];
                   15568:        if (c == ':' || (cp=strchr(opts, c)) == NULL) {
                   15569:                ERR("illegal option -- ", c);
                   15570:                if (argv[optind][++sp] == '\0') {
                   15571:                        optind++;
                   15572:                        sp = 1;
                   15573:                }
                   15574:                optarg = NULL;
                   15575:                return('?');
                   15576:        }
                   15577:        if (*++cp == ':') {
                   15578: #ifdef FASCIST
                   15579:                if (sp != 1) {
                   15580:                        ERR("option must not be grouped -- ", c );
                   15581:                        optind++;
                   15582:                        sp = 1;
                   15583:                        optarg = NULL;
                   15584:                        return('?');
                   15585:                } else
                   15586: #endif
                   15587:                if (argv[optind][sp+1] != '\0') {
                   15588: #ifdef FASCIST
                   15589:                        ERR("option must be followed by whitespace -- ", c );
                   15590:                        optind++;
                   15591:                        sp = 1;
                   15592:                        optarg = NULL;
                   15593:                        return('?');
                   15594: #else
                   15595:                        optarg = &argv[optind++][sp+1];
                   15596: #endif
                   15597:                } else if (++optind >= argc) {
                   15598:                        ERR("option requires an argument -- ", c);
                   15599:                        sp = 1;
                   15600:                        optarg = NULL;
                   15601:                        return('?');
                   15602:                } else
                   15603:                        optarg = argv[optind++];
                   15604:                sp = 1;
                   15605:        } else {
                   15606:                if (argv[optind][++sp] == '\0') {
                   15607:                        sp = 1;
                   15608:                        optind++;
                   15609:                }
                   15610:                optarg = NULL;
                   15611:        }
                   15612:        return(c);
                   15613: }
                   15614: 
                   15615: /*
                   15616:  * The following were created by Arnold Robbins.
                   15617:  */
                   15618: 
                   15619: /* resetopts --- magic code for when OPTIND is reset to 1 */
                   15620: 
                   15621: void
                   15622: resetopts ()
                   15623: {
                   15624:        optind = 1;
                   15625:        sp = 1;
                   15626: }
                   15627: 
                   15628: int
                   15629: c_getopts(wp)
                   15630:        char **wp;
                   15631: {
                   15632:        int ret;
                   15633:        register int argc;
                   15634:        char temp[2];
                   15635:        char *optstr;                   /* list of options */
                   15636:        char *name;                     /* variable to get flag val */
                   15637:        char **argv;
                   15638: 
                   15639:        if ((optstr = *++wp) == NULL || (name = *++wp) == NULL)
                   15640:                errorf("missing arguments\n");
                   15641: 
                   15642:        for (argc = 1; wp[argc] != NULL; argc++)
                   15643:                ;
                   15644: 
                   15645:        if (argc > 1)
                   15646:                ret = getopt(argc, wp, optstr);
                   15647:        else {
                   15648:                if (**(e.loc->argv) == '\0') {
                   15649:                        /*
                   15650:                         * When c_getopts gets called from comexec() it
                   15651:                         * doesn't set up argc/argv in the local block.
                   15652:                         * Maybe this should be done in newblock() but
                   15653:                         * I'm not sure about the implications, and this
                   15654:                         * is the only place I've been bitten so far...
                   15655:                         * JRM
                   15656:                         */
                   15657:                        argc = e.loc->next->argc;
                   15658:                        argv = e.loc->next->argv;
                   15659:                } else {
                   15660:                        argc = e.loc->argc;
                   15661:                        argv = e.loc->argv;
                   15662:                }
                   15663:                ret = getopt(argc+1, argv, optstr);
                   15664: 
                   15665:        }
                   15666: 
                   15667:        /*
                   15668:         * set the OPTIND variable in any case, to handle "--" skipping
                   15669:         * unless it's 1, which would trigger a reset
                   15670:         */
                   15671: 
                   15672:        if (optind != 1)
                   15673:                setint(global("OPTIND"), (long)optind);
                   15674: 
                   15675:        if (ret == GETOPTEOF)           /* end of args */
                   15676:                return (1);
                   15677: 
                   15678:        /*
                   15679:         * else, got an arg, set the various shell variables
                   15680:         */
                   15681: 
                   15682:        if (optarg != NULL)
                   15683:                setstr(global("OPTARG"), optarg);
                   15684: 
                   15685:        temp[0] = (char) ret;
                   15686:        temp[1] = '\0';
                   15687:        setstr(global(name), temp);
                   15688: 
                   15689:        return (0);
                   15690: }
                   15691: ./pdksh/sh/io.c   644    653   1762        6537  5303016706  10601 0ustar  hlu/*
                   15692:  * shell buffered IO and formatted output
                   15693:  */
                   15694: 
                   15695: #ifndef lint
                   15696: static char *RCSid = "$Id: io.c,v 1.3 1992/08/10 12:02:49 sjg Exp $";
                   15697: #endif
                   15698: 
                   15699: #include "stdh.h"
                   15700: #include <errno.h>
                   15701: #include <unistd.h>
                   15702: #include <fcntl.h>
                   15703: #include <signal.h>
                   15704: #include <setjmp.h>
                   15705: #ifdef __STDC__
                   15706: #include <stdarg.h>
                   15707: #else
                   15708: #include <varargs.h>
                   15709: #endif
                   15710: #include "sh.h"
                   15711: 
                   15712: #if 0
                   15713: /* fputc with ^ escaping */
                   15714: static void
                   15715: fzotc(c, f)
                   15716:        register int c;
                   15717:        register FILE *f;
                   15718: {
                   15719:        if ((c&0x60) == 0) {            /* C0|C1 */
                   15720:                putc((c&0x80) ? '$' : '^', f);
                   15721:                putc((c&0x7F|0x40), f);
                   15722:        } else if ((c&0x7F) == 0x7F) {  /* DEL */
                   15723:                putc((c&0x80) ? '$' : '^', f);
                   15724:                putc('?', f);
                   15725:        } else
                   15726:                putc(c, f);
                   15727: }
                   15728: #endif
                   15729: 
                   15730: /*
                   15731:  * formatted output functions
                   15732:  */
                   15733: 
                   15734: /* shellf(...); error() */
                   15735: int
                   15736: #ifdef __STDC__
                   15737: errorf(const char *fmt, ...) {
                   15738: #else
                   15739: errorf(va_alist) va_dcl
                   15740: {
                   15741:        char *fmt;
                   15742: #endif
                   15743:        va_list va;
                   15744: 
                   15745: #ifdef __STDC__
                   15746:        va_start(va, fmt);
                   15747: #else
                   15748:        va_start(va);
                   15749:        fmt = va_arg(va, char *);
                   15750: #endif
                   15751:        vfprintf(shlout, fmt, va);
                   15752:        va_end(va);
                   15753:        /*fflush(shlout);*/
                   15754:        error();
                   15755: }
                   15756: 
                   15757: /* printf to shlout (stderr) */
                   15758: int
                   15759: #ifdef __STDC__
                   15760: shellf(const char *fmt, ...) {
                   15761: #else
                   15762: shellf(va_alist) va_dcl
                   15763: {
                   15764:        char *fmt;
                   15765: #endif
                   15766:        va_list va;
                   15767: 
                   15768: #ifdef __STDC__
                   15769:        va_start(va, fmt);
                   15770: #else
                   15771:        va_start(va);
                   15772:        fmt = va_arg(va, char *);
                   15773: #endif
                   15774:        vfprintf(shlout, fmt, va);
                   15775:        va_end(va);
                   15776:        return 0;
                   15777: }
                   15778: 
                   15779: /*
                   15780:  * We have a stdio stream for any open shell file descriptors (0-9)
                   15781:  */
                   15782: FILE * shf [NUFILE];           /* map shell fd to FILE * */
                   15783: 
                   15784: /* open stream for shell fd */
                   15785: void
                   15786: fopenshf(fd)
                   15787:        int fd;
                   15788: {
                   15789:        if (shf[fd] != NULL)
                   15790:                return;
                   15791: #if !defined(_MINIX) && !defined(linux)
                   15792:        if (fd <= 2)
                   15793: #ifndef _BSDI
                   15794:                _iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */
                   15795: #else
                   15796:                /* Chris Torek's stdio replacement */
                   15797:                __sF[fd]._flags = 0;
                   15798: #endif
                   15799: #endif
                   15800:        shf[fd] = fdopen(fd, "r+");
                   15801:        if (shf[fd] == NULL)
                   15802:                return;
                   15803:        setvbuf(shf[fd], (char*)NULL, _IOFBF, (size_t)BUFSIZ);
                   15804: }
                   15805: 
                   15806: /* flush stream assoc with fd */
                   15807: /* this must invalidate input and output buffers */
                   15808: void
                   15809: flushshf(fd)
                   15810:        int fd;
                   15811: {
                   15812:        if (shf[fd] != NULL) {
                   15813: #ifndef _BSDI
                   15814:                /* Chris Torek's stdio replacement */
                   15815:                fseek(shf[fd], 0L, 1); /* V7 derived */
                   15816: #endif
                   15817:                fflush(shf[fd]);        /* standard C */
                   15818:        }
                   15819: }
                   15820: 
                   15821: /*
                   15822:  * move fd from user space (0<=fd<10) to shell space (fd>=10)
                   15823:  */
                   15824: int
                   15825: savefd(fd)
                   15826:        int fd;
                   15827: {
                   15828:        int nfd;
                   15829: 
                   15830:        if (fd < FDBASE) {
                   15831:                flushshf(fd);
                   15832:                nfd = fcntl(fd, F_DUPFD, FDBASE);
                   15833:                if (nfd < 0)
                   15834:                        if (errno == EBADF)
                   15835:                                return -1;
                   15836:                        else
                   15837:                                errorf("too many files open in shell\n");
                   15838: #ifdef F_SETFD
                   15839:                (void) fcntl(nfd, F_SETFD, 1);
                   15840: #else
                   15841:                (void) fd_clexec(ttyfd);
                   15842: #endif
                   15843:                close(fd);
                   15844:        } else
                   15845:                nfd = fd;
                   15846:        return nfd;
                   15847: }
                   15848: 
                   15849: void
                   15850: restfd(fd, ofd)
                   15851:        int fd, ofd;
                   15852: {
                   15853:        if (ofd == 0)           /* not saved (e.savefd) */
                   15854:                return;
                   15855:        flushshf(fd);
                   15856:        close(fd);
                   15857:        if (ofd < 0)            /* original fd closed */
                   15858:                return;
                   15859:        (void) fcntl(ofd, F_DUPFD, fd);
                   15860:        close(ofd);
                   15861: }
                   15862: 
                   15863: void
                   15864: openpipe(pv)
                   15865:        register int *pv;
                   15866: {
                   15867:        if (pipe(pv) < 0)
                   15868:                errorf("can't create pipe - try again\n");
                   15869:        pv[0] = savefd(pv[0]);
                   15870:        pv[1] = savefd(pv[1]);
                   15871: }
                   15872: 
                   15873: void
                   15874: closepipe(pv)
                   15875:        register int *pv;
                   15876: {
                   15877:        close(pv[0]);
                   15878:        close(pv[1]);
                   15879: }
                   15880: 
                   15881: /*
                   15882:  * temporary files
                   15883:  */
                   15884: 
                   15885: struct temp *
                   15886: maketemp(ap)
                   15887:        Area *ap;
                   15888: {
                   15889:        register struct temp *tp;
                   15890:        static unsigned int inc = 0;
                   15891:        char path [PATH];
                   15892: 
                   15893:        sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++);
                   15894: #if defined(_SYSV) || defined(_BSD)
                   15895:        close(creat(path, 0600));       /* to get appropriate permissions */
                   15896: #endif
                   15897:        tp = (struct temp *) alloc(sizeof(struct temp), ap);
                   15898:        tp->next = NULL;
                   15899:        tp->name = strsave(path, ap);
                   15900:        return tp;
                   15901: }
                   15902: ./pdksh/sh/lex.h   644    653   1762        7106  5243743702  10766 0ustar  hlu/*
                   15903:  * Source input, lexer and parser
                   15904:  */
                   15905: 
                   15906: /* $Id: lex.h,v 1.4 1992/08/12 14:15:37 sjg Exp $ */
                   15907: 
                   15908: #define        IDENT   64
                   15909: 
                   15910: typedef struct source Source;
                   15911: struct source {
                   15912:        char   *str;            /* input pointer */
                   15913:        int     type;           /* input type */
                   15914:        union {
                   15915:                char  **strv;   /* string [] */
                   15916:                FILE   *file;   /* file */
                   15917:                struct tbl *tblp; /* alias */
                   15918:        } u;
                   15919:        int     line;           /* line number */
                   15920:        char   *file;           /* input file name */
                   15921:        int     echo;           /* echo input to shlout */
                   15922:        Source *next;           /* stacked source */
                   15923: };
                   15924: 
                   15925: /* Source.type values */
                   15926: #define        SEOF    0               /* input EOF */
                   15927: #define        STTY    1               /* terminal input */
                   15928: #define        SFILE   2               /* file input */
                   15929: #define        SSTRING 4               /* string */
                   15930: #define        SWSTR   3               /* string without \n */
                   15931: #define        SWORDS  5               /* string[] */
                   15932: #define        SWORDSEP 8              /* string[] seperator */
                   15933: #define        SALIAS  6               /* alias expansion */
                   15934: #define        SHIST   7               /* history expansion */
                   15935: 
                   15936: Source *pushs ARGS((int stype));       /* push Source */
                   15937: struct op *compile ARGS((Source *s));  /* compile tree */
                   15938: 
                   15939: /*
                   15940:  * states while lexing word
                   15941:  */
                   15942: #define        SBASE   0               /* outside any lexical constructs */
                   15943: #define        SWORD   6               /* implicit quoting for substitute() */
                   15944: #define        SDPAREN 7               /* inside (( )), implicit quoting */
                   15945: #define        SSQUOTE 1               /* inside '' */
                   15946: #define        SDQUOTE 2               /* inside "" */
                   15947: #define        SBRACE  3               /* inside ${} */
                   15948: #define        SPAREN  4               /* inside $() */
                   15949: #define        SBQUOTE 5               /* inside `` */
                   15950: 
                   15951: EXTERN int     multiline;      /* \n changed to ; */
                   15952: 
                   15953: typedef union {
                   15954:        int     i;
                   15955:        char   *cp;
                   15956:        char  **wp;
                   15957:        struct op *o;
                   15958:        struct ioword *iop;
                   15959: } YYSTYPE;
                   15960: 
                   15961: #define        LWORD   256
                   15962: #define        LOGAND  257
                   15963: #define        LOGOR   258
                   15964: #define        BREAK   259
                   15965: #define        IF      260
                   15966: #define        THEN    261
                   15967: #define        ELSE    262
                   15968: #define        ELIF    263
                   15969: #define        FI      264
                   15970: #define        CASE    265
                   15971: #define        ESAC    266
                   15972: #define        FOR     267
                   15973: #define        WHILE   268
                   15974: #define        UNTIL   269
                   15975: #define        DO      270
                   15976: #define        DONE    271
                   15977: #define        IN      272
                   15978: #define        FUNCTION 273
                   15979: #define        TIME    274
                   15980: #define        REDIR   275
                   15981: #define        MPAREN  276             /* () */
                   15982: #define        MDPAREN 277             /* (( )) */
                   15983: #define SELECT 278             /* ksh */
                   15984: #define        YYERRCODE 300
                   15985: 
                   15986: /* flags to yylex */
                   15987: #define        CONTIN  BIT(0)          /* skip new lines to complete command */
                   15988: #define        ONEWORD BIT(1)          /* single word for substitute() */
                   15989: #define        ALIAS   BIT(2)          /* recognize alias */
                   15990: #define        KEYWORD BIT(3)          /* recognize keywords */
                   15991: #define        LETEXPR BIT(4)          /* get expression inside (( )) */
                   15992: 
                   15993: #define        SYNTAXERR       zzerr()
                   15994: #define        HERES   10              /* max << in line */
                   15995: 
                   15996: EXTERN char    line [LINE+1];  /* input line */
                   15997: EXTERN Source *source;         /* yyparse/yylex source */
                   15998: EXTERN YYSTYPE yylval;         /* result from yylex */
                   15999: EXTERN int     yynerrs;
                   16000: EXTERN struct ioword *heres [HERES], **herep;
                   16001: EXTERN char    ident [IDENT+1];
                   16002: 
                   16003: extern int     yylex ARGS((int flags));
                   16004: extern void    yyerror ARGS((const char *msg));
                   16005: 
                   16006: #define        HISTORY 100             /* size of saved history */
                   16007: 
                   16008: #ifdef EASY_HISTORY
                   16009: EXTERN char   *history [HISTORY];      /* saved commands */
                   16010: #else
                   16011: EXTERN  char   **history;              /* saved commands */
                   16012: EXTERN int     histsize _I_(HISTORY);  /* history size */
                   16013: EXTERN char  **history;        /* saved commands */
                   16014: #endif
                   16015: EXTERN char  **histptr;        /* last history item */
                   16016: EXTERN int     histpush;       /* number of pushed fc commands */
                   16017: 
                   16018: extern char    **histget();
                   16019: extern  char   **histpos();
                   16020: extern int     histnum();
                   16021: extern char    *findhist();
                   16022: extern int     histN();
                   16023: 
                   16024: #ifdef EDIT
                   16025: 
                   16026: extern void    x_init ARGS ((void));   /* setup tty modes */
                   16027: extern void    x_init_emacs ARGS ((void));
                   16028: extern void    x_emacs_keys ();
                   16029: extern void    x_bind();
                   16030: 
                   16031: extern int     x_read ARGS ((int fd, char *buf, size_t len));
                   16032: extern int     x_emacs ARGS ((char *buf, size_t len));
                   16033: extern int     x_vi ARGS ((char *buf, size_t len));
                   16034: 
                   16035: extern bool_t  x_mode ARGS ((bool_t)); /* set/clear cbreak mode */
                   16036: extern int     x_getc();               /* get tty char */
                   16037: extern void    x_flush(), x_putc(), x_puts(); /* put tty char */
                   16038: 
                   16039: extern int     x_cols;         /* tty columns */
                   16040: 
                   16041: #endif
                   16042: ./pdksh/sh/table.h   644    653   1762        7125  5243743701  11265 0ustar  hlu/* $Id: table.h,v 1.4 1992/08/12 14:15:50 sjg Exp $ */
                   16043: 
                   16044: /*
                   16045:  * generic hashed associative table for commands and variables.
                   16046:  */
                   16047: 
                   16048: struct table {
                   16049:        Area   *areap;          /* area to allocate entries */
                   16050:        int     size, free;     /* hash size (always 2^^n), free entries */
                   16051:        struct  tbl **tbls;     /* hashed table items */
                   16052: };
                   16053: 
                   16054: struct tbl {                   /* table item */
                   16055:        int     flag;           /* flags */
                   16056:        int     type;           /* command type or base, see below */
                   16057:        union {
                   16058:                char *s;        /* string */
                   16059:                long i;         /* integer */
                   16060:                int (*f) ARGS ((char**)); /* int function */
                   16061:                struct op *t;   /* "function" tree */
                   16062:        } val;                  /* value */
                   16063:        char    name[4];        /* name -- variable length */
                   16064: };
                   16065: 
                   16066: /* flag bits */
                   16067: #define        ALLOC   BIT(0)          /* val.s has been allocated */
                   16068: #define        DEFINED BIT(1)          /* is defined in block */
                   16069: #define        ISSET   BIT(2)          /* has value, vp->val.[si] */
                   16070: #define        SPECIAL BIT(3)          /* PATH, IFS, SECONDS, etc */
                   16071: #define        INTEGER BIT(4)          /* val.i contains integer value */
                   16072: #define        RDONLY  BIT(8)          /* read-only variable */
                   16073: #define        EXPORT  BIT(9)          /* exported variable */
                   16074: #define        LOCAL   BIT(10)         /* for local typeset() */
                   16075: #define        TRACE   BIT(11)         /* trace (-t) */
                   16076: #define        FUNCT   BIT(12)         /* function */
                   16077: #define        EXPALIAS BIT(13)        /* expanding this alias */
                   16078: 
                   16079: /* command types */
                   16080: #define        CNONE   0               /* undefined */
                   16081: #define        CSHELL  1               /* built-in */
                   16082: #define        CFUNC   2               /* function */
                   16083: #define        CEXEC   4               /* executable command */
                   16084: #define        CALIAS  5               /* alias */
                   16085: #define        CKEYWD  6               /* keyword */
                   16086: 
                   16087: void tinit ARGS((struct table *, Area *)); /* initialize table */
                   16088: unsigned int hash();           /* name hash function */
                   16089: struct tbl *tsearch();         /* table lookup primative */
                   16090: struct tbl *tenter();          /* table lookup/enter primative */
                   16091: void tdelete();                        /* mark tbl entry for deletion */
                   16092: void twalk();                  /* initialize walk of table */
                   16093: struct tbl *tnext();           /* walk table returning table time */
                   16094: struct tbl **tsort();          /* sort table entries by name */
                   16095: 
                   16096: /*
                   16097:  * activation record for function blocks
                   16098:  */
                   16099: struct block {
                   16100:        Area    area;           /* area to allocate things */
                   16101:        int     argc;           /* current $# */
                   16102:        char ** argv;           /* current $* */
                   16103:        struct  table vars;     /* local variables */
                   16104:        struct  table funs;     /* local functions */
                   16105: #if 1
                   16106:        char *  error;          /* error handler */
                   16107:        char *  exit;           /* exit handler */
                   16108: #else
                   16109:        struct  trap error, exit;
                   16110: #endif
                   16111:        struct  block *next;    /* enclosing block */
                   16112: };
                   16113: 
                   16114: EXTERN struct block globals;   /* global variables and functions */
                   16115: EXTERN struct table commands;  /* hashed commands */
                   16116: EXTERN struct table builtins;  /* built-in commands */
                   16117: EXTERN struct table lexicals;  /* keywords and aliases */
                   16118: EXTERN struct table homedirs;  /* homedir() cache */
                   16119: 
                   16120: struct builtin {
                   16121:        char   *name;
                   16122:        int  (*func)();
                   16123: };
                   16124: 
                   16125: /* these really are externs! Look in table.c for them */
                   16126: 
                   16127: extern const struct builtin shbuiltins [], kshbuiltins [];
                   16128: 
                   16129: /* var spec values */
                   16130: #define        V_NONE  0
                   16131: #define        V_PATH  1
                   16132: #define        V_IFS   2
                   16133: #define        V_SECONDS 3
                   16134: #define        V_OPTIND 4
                   16135: #define        V_MAIL  5
                   16136: #define        V_MAILPATH 6
                   16137: #define        V_RANDOM 7
                   16138: #ifndef EASY_HISTORY
                   16139: #define V_HISTSIZE 8
                   16140: #define V_HISTFILE 9
                   16141: #endif
                   16142: #define V_FCEDIT 10
                   16143: #define V_COLUMNS 11
                   16144: 
                   16145: EXTERN Area   *lastarea;       /* area of last variable/function looked up */
                   16146: EXTERN char   *path;           /* PATH value */
                   16147: EXTERN char   *prompt;         /* PS1 or PS2 */
                   16148: 
                   16149: void   newblock();
                   16150: void   popblock();
                   16151: struct tbl *global(/* char *s */);
                   16152: struct tbl *local(/* char *s */);
                   16153: struct tbl *typeset(/* char *var; int set, clr */);
                   16154: struct tbl *setvar(/* struct tbl *vdst, *vsrc */);
                   16155: struct tbl *strint(/* struct tbl *vdst, *vsrc */);
                   16156: long   intval(/* struct tbl *vp */);
                   16157: void   setint(/* struct tbl *vp; long n */);
                   16158: char   *strval(/* struct tbl *vp */);
                   16159: void   setstr(/* struct tbl *vp; char *s */);
                   16160: void   unset(/* struct tbl *vp */);
                   16161: int    import(/* char *s */);
                   16162: char  **makenv();
                   16163: int    isassign(/* char *s */);
                   16164: 
                   16165: ./pdksh/sh/trace.h   644    653   1762        4160  5243743615  11274 0ustar  hlu/* NAME:
                   16166:  *      trace.h - definitions for a simple trace facility
                   16167:  *
                   16168:  * SYNOPSIS:
                   16169:  *      #include "trace.h"
                   16170:  *
                   16171:  * DESCRIPTION:
                   16172:  *      Defines the macro _TRACE().
                   16173:  *      Also declares Trace_log and Trace_level.
                   16174:  *
                   16175:  * SEE ALSO:
                   16176:  *      
                   16177:  *
                   16178:  * AMENDED:
                   16179:  *      91/11/22  22:53:58  (sjg)
                   16180:  *
                   16181:  * RELEASED:
                   16182:  *      91/11/22  22:54:18  v1.2
                   16183:  *
                   16184:  * SCCSID:
                   16185:  *      @(#)trace.h  1.2  91/11/22  22:53:58  (sjg)
                   16186:  *
                   16187:  *      @(#)Copyright (c) 1990 Simon J. Gerraty.
                   16188:  */
                   16189: 
                   16190: /* some useful #defines */
                   16191: #ifndef EXTERN
                   16192: # define EXTERN extern
                   16193: # define EXTERN_DEFINED
                   16194: #endif
                   16195: 
                   16196: #ifndef TRUE
                   16197: # define TRUE  1
                   16198: # define FALSE 0
                   16199: #endif
                   16200: #ifndef ARGS
                   16201: # if defined(__STDC__) || defined(PROTO)
                   16202: #   define ARGS(p) p
                   16203: # else
                   16204: #   define ARGS(p) ()
                   16205: # endif
                   16206: #endif
                   16207: 
                   16208: /*
                   16209:  * this garbage is sometimes needed when mixing
                   16210:  * langauges or calling conventions under DOS.
                   16211:  */
                   16212: #ifndef _CDECL
                   16213: # if defined(MSDOS) || defined(MSC)
                   16214: #   ifndef NO_EXT_KEYS
                   16215: #     define _CDECL  cdecl
                   16216: #     define _NEAR   near
                   16217: #   else
                   16218: #     define _CDECL
                   16219: #     define _NEAR
                   16220: #   endif
                   16221: # else /* not DrOS */
                   16222: #   define _CDECL
                   16223: #   define _NEAR
                   16224: # endif /* DOS */
                   16225: #endif /* _CDECL */
                   16226: 
                   16227: /* manifest constants */
                   16228: 
                   16229: /* struct / union */
                   16230: 
                   16231: /* macros */
                   16232: 
                   16233: 
                   16234: #ifdef USE_TRACE
                   16235: EXTERN char * _CDECL   Trace_log;
                   16236: EXTERN int _CDECL      Trace_level;
                   16237: 
                   16238: void _CDECL checkpoint ARGS((char *fmt, ...));
                   16239: 
                   16240: /*
                   16241:  * This macro takes a variabel number of args. 
                   16242:  * examples:
                   16243:  *     _TRACE(5, ("The current Debug level is %d\n", Debug));
                   16244:  * Note that if more than two args are provided, all but the 
                   16245:  * first (which should be an integer indicating the Trace-level 
                   16246:  * required for this message to be printed) must be enclosed in 
                   16247:  * parenthesis. 
                   16248:  */
                   16249: # define _TRACE(lev, args) if (Trace_level >= lev) checkpoint args
                   16250: #else  /* don't USE_TRACE */
                   16251:   /*
                   16252:    * this macro evaluates to a harmless no entry
                   16253:    * loop that most optimizers will remove all together.
                   16254:    */
                   16255: # define _TRACE(l, args) while (0)
                   16256: #endif         /* USE_TRACE */
                   16257: 
                   16258: 
                   16259: /* This lot goes at the END */
                   16260: /* be sure not to interfere with anyone else's idea about EXTERN */
                   16261: #ifdef EXTERN_DEFINED
                   16262: # undef EXTERN_DEFINED
                   16263: # undef EXTERN
                   16264: #endif
                   16265: /*
                   16266:  * Local Variables:
                   16267:  * version-control:t
                   16268:  * comment-column:40
                   16269:  * End:
                   16270:  */
                   16271: ./pdksh/sh/trap.c   644    653   1762       11410  5302761055  11145 0ustar  hlu/*
                   16272:  * signal handling
                   16273:  */
                   16274: 
                   16275: #ifndef lint
                   16276: static char *RCSid = "$Id: trap.c,v 1.3 1992/08/10 12:03:15 sjg Exp $";
                   16277: #endif
                   16278: 
                   16279: #include "stdh.h"
                   16280: #include <errno.h>
                   16281: #include <signal.h>
                   16282: #include <setjmp.h>
                   16283: #include "sh.h"
                   16284: 
                   16285: Trap sigtraps [SIGNALS] = {
                   16286:        {0,     "EXIT", "Signal 0"}, /* todo: belongs in e.loc->exit */
                   16287:        {SIGHUP, "HUP", "Hangup"},
                   16288:        {SIGINT, "INT", "Interrupt"},
                   16289:        {SIGQUIT, "QUIT", "Quit"},
                   16290:        {SIGILL, "ILL", "Illegal instruction"},
                   16291:        {SIGTRAP, "TRAP", "Trace trap"},
                   16292: #ifdef SIGABRT
                   16293:        {SIGIOT, "ABRT", "Abort"},
                   16294: #else
                   16295:        {SIGIOT, "IOT", "IOT instruction"},
                   16296: #endif
                   16297: #ifdef linux
                   16298:        {SIGUNUSED, "UNUSED", "Unused signal"},
                   16299: #else
                   16300:        {SIGEMT, "EMT", "EMT trap"},
                   16301: #endif
                   16302:        {SIGFPE, "FPE", "Floating exception"},
                   16303:        {SIGKILL, "KILL", "Killed"},
                   16304: #if defined(_MINIX) || defined(linux)
                   16305:        {SIGUSR1, "USR1", "User defined signal 1"},
                   16306:        {SIGSEGV, "SEGV", "Memory fault"},
                   16307:        {SIGUSR2, "USR2", "User defined signal 2"},
                   16308: #else
                   16309:        {SIGBUS, "BUS", "Bus error"},
                   16310:        {SIGSEGV, "SEGV", "Memory fault"},
                   16311:        {SIGSYS, "SYS", "Bad system call"},
                   16312: #endif
                   16313:        {SIGPIPE, "PIPE", "Broken pipe"},
                   16314:        {SIGALRM, "ALRM", "Alarm clock"},
                   16315:        {SIGTERM, "TERM", "Terminated"},
                   16316: #if defined(_MINIX) || defined(linux)
                   16317:        {SIGSTKFLT, "STKFLT", "Stack fault"},
                   16318: #endif
                   16319: #ifdef linux
                   16320:        {SIGCHLD, "CHLD", "Child exited"},
                   16321:        {SIGCONT, "CONT", "Continue"},
                   16322:        {SIGSTOP, "STOP", "Stop (signal)"},
                   16323:        {SIGTSTP, "TSTP", "Stop"},
                   16324:        {SIGTTIN, "TTIN", "Stop (tty input)"},
                   16325:        {SIGTTOU, "TTOU", "Stop (tty output)"},
                   16326:        {SIGIO, "IO", "Possible I/O"},
                   16327:        {SIGXCPU, "XCPU", "CPU time limit exceeded"},
                   16328:        {SIGXFSZ, "XFSZ", "File size limit exceeded"},
                   16329:        {SIGVTALRM, "VTALRM", "Virtual time alarm"},
                   16330:        {SIGPROF, "PROF", "Profile signal"},
                   16331:        {SIGWINCH, "WINCH", "Window size changed"},
                   16332: #ifdef SIGLOST
                   16333:        {SIGLOST, "LOST", "File lock lost"},
                   16334: #endif
                   16335: #else
                   16336: #ifdef _SYSV
                   16337:        {SIGUSR1, "USR1", "User defined signal 1"},
                   16338:        {SIGUSR2, "USR2", "User defined signal 2"},
                   16339:        {SIGCLD, "CLD", "Death of a child"},
                   16340:        {SIGPWR, "PWR", "Power-fail restart"},
                   16341: #ifdef JOBS                    /* todo: need to be more portable */
                   16342:        {SIGTSTP, "TSTP", "Stop"},
                   16343:        {SIGTTIN, "TTIN", "Stop (tty input)"},
                   16344: #ifdef SIGPOLL
                   16345:        {SIGPOLL, "POLL", "Pollable event occured"},
                   16346: #endif
                   16347:        {SIGSTOP, "STOP", "Stop (signal)"},
                   16348:        {SIGTTOU, "TTOU", "Stop (tty output)"},
                   16349:        {SIGCONT, "CONT", "Continue"},
                   16350: #endif
                   16351: #else  /* _SYSV */
                   16352: #ifdef JOBS                    /* todo: need to be more portable */
                   16353:        {SIGURG, "URG", "Urgent condition"}, /* BSDism */
                   16354:        {SIGSTOP, "STOP", "Stop (signal)"},
                   16355:        {SIGTSTP, "TSTP", "Stop"},
                   16356:        {SIGCONT, "CONT", "Continue"},
                   16357:        {SIGCHLD, "CHLD", "Waiting children"},
                   16358:        {SIGTTIN, "TTIN", "Stop (tty input)"},
                   16359:        {SIGTTOU, "TTOU", "Stop (tty output)"},
                   16360: #endif
                   16361: #endif /* _SYSV */
                   16362: #endif /* linux */
                   16363: };
                   16364: 
                   16365: Trap *
                   16366: gettrap(name)
                   16367:        char *name;
                   16368: {
                   16369:        int i;
                   16370:        register Trap *p;
                   16371: 
                   16372:        if (digit(*name)) {
                   16373:                i = getn(name);
                   16374:                return (0 <= i && i < SIGNALS) ? &sigtraps[getn(name)] : NULL;
                   16375:        }
                   16376: #if 0
                   16377:        if (strcmp("ERR", name) == 0)
                   16378:                return &e.loc->err;
                   16379:        if (strcmp("EXIT", name) == 0)
                   16380:                return &e.loc->exit;
                   16381: #endif
                   16382:        for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
                   16383:                if (p->name != NULL && strcmp(p->name, name) == 0)
                   16384:                        return p;
                   16385:        return NULL;
                   16386: }
                   16387: 
                   16388: /*
                   16389:  * trap signal handler
                   16390:  */
                   16391: void
                   16392: trapsig(i)
                   16393:        int i;
                   16394: {
                   16395:        trap = sigtraps[i].set = 1;
                   16396:        if (i == SIGINT && (e.type == E_PARSE || e.type == E_LOOP))
                   16397:                /* dangerous but necessary to deal with BSD silly signals */
                   16398:                longjmp(e.jbuf, 1);
                   16399: #ifdef USE_SIGACT
                   16400:        sigaction(i, &Sigact_trap, NULL);
                   16401: #else
                   16402:        (void) signal(i, trapsig);
                   16403: #endif
                   16404: }
                   16405: 
                   16406: /*
                   16407:  * run any pending traps
                   16408:  */
                   16409: runtraps()
                   16410: {
                   16411:        int i;
                   16412:        register Trap *p;
                   16413: 
                   16414:        for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
                   16415:                if (p->set)
                   16416:                        runtrap(p);
                   16417:        trap = 0;
                   16418: }
                   16419: 
                   16420: runtrap(p)
                   16421:        Trap *p;
                   16422: {
                   16423:        char *trapstr;
                   16424: 
                   16425:        p->set = 0;
                   16426:        if ((trapstr = p->trap) == NULL)
                   16427:                if (p->signal == SIGINT)
                   16428:                        unwind();       /* return to shell() */
                   16429:                else
                   16430:                        return;
                   16431:        if (p->signal == 0)     /* ??? */
                   16432:                p->trap = 0;
                   16433:        command(trapstr);
                   16434: }
                   16435:  
                   16436: /* restore signals for children */
                   16437: cleartraps()
                   16438: {
                   16439:        int i;
                   16440:        register Trap *p;
                   16441: 
                   16442:        if ((p = sigtraps)->trap != NULL) {     /* Maybe put in exchild() */
                   16443:                afree((void *)p->trap,APERM);   /* Necessary? */
                   16444:                p->trap = NULL;
                   16445:        }
                   16446:        for (i = SIGNALS, p = sigtraps; --i >= 0; p++) {
                   16447:                p->set = 0;
                   16448: #ifdef USE_SIGACT
                   16449:                if (p->ourtrap)
                   16450:                {
                   16451:                  sigaction(p->signal, &Sigact_ign, &Sigact);
                   16452:                  if (Sigact.sa_handler != SIG_IGN)
                   16453:                    sigaction(p->signal, &Sigact_dfl, NULL);
                   16454:                }
                   16455: #else
                   16456:                if (p->ourtrap && signal(p->signal, SIG_IGN) != SIG_IGN)
                   16457:                        (void) signal(p->signal, SIG_DFL);
                   16458: #endif
                   16459:        }
                   16460: }
                   16461: 
                   16462: ignoresig(i)
                   16463:        int i;
                   16464: {
                   16465: #ifdef USE_SIGACT
                   16466:   sigaction(i, &Sigact_ign, &Sigact);
                   16467:   sigemptyset(&Sigact.sa_mask);
                   16468:   Sigact.sa_flags = 0;
                   16469: 
                   16470:   if (Sigact.sa_handler != SIG_IGN)
                   16471:     sigtraps[i].sig_dfl = 1;
                   16472: #else
                   16473:   if (signal(i, SIG_IGN) != SIG_IGN)
                   16474:     sigtraps[i].sig_dfl = 1;
                   16475: #endif
                   16476: }
                   16477: 
                   16478: restoresigs()
                   16479: {
                   16480:        int i;
                   16481:        register Trap *p;
                   16482: 
                   16483:        for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
                   16484:                if (p->sig_dfl) {
                   16485:                        p->sig_dfl = 0;
                   16486: #ifdef USE_SIGACT
                   16487:                        sigaction(p->signal, &Sigact_dfl, NULL);
                   16488: #else
                   16489:                        (void) signal(p->signal, SIG_DFL);
                   16490: #endif
                   16491:                }
                   16492: }
                   16493: 
                   16494: ./pdksh/sh/tree.h   644    653   1762        7130  5243743666  11143 0ustar  hlu/*
                   16495:  * command trees for compile/execute
                   16496:  */
                   16497: 
                   16498: /* $Id: tree.h,v 1.3 1992/08/10 12:03:18 sjg Exp $ */
                   16499: 
                   16500: #define        NOBLOCK ((struct op *)NULL)
                   16501: #define        NOWORD  ((char *)NULL)
                   16502: #define        NOWORDS ((char **)NULL)
                   16503: 
                   16504: /*
                   16505:  * Description of a command or an operation on commands.
                   16506:  */
                   16507: struct op {
                   16508:        int     type;                   /* operation type, see below */
                   16509:        char  **args;                   /* arguments to a command */
                   16510:        char  **vars;                   /* variable assignments */
                   16511:        struct ioword   **ioact;        /* IO actions (eg, < > >>) */
                   16512:        struct op *left, *right;        /* descendents */
                   16513:        char   *str;            /* identifier for case and for (use vars[0]) */
                   16514: };
                   16515: 
                   16516: /* Tree.type values */
                   16517: #define        TEOF    0
                   16518: #define        TCOM    1               /* command */
                   16519: #define        TPAREN  2               /* (c-list) */
                   16520: #define        TPIPE   3               /* a | b */
                   16521: #define        TLIST   4               /* a [&;] b */
                   16522: #define        TOR     5               /* || */
                   16523: #define        TAND    6               /* && */
                   16524: #define        TFOR    7
                   16525: #define        TCASE   9
                   16526: #define        TIF     10
                   16527: #define        TWHILE  11
                   16528: #define        TUNTIL  12
                   16529: #define        TELIF   13
                   16530: #define        TPAT    14              /* pattern in case */
                   16531: #define        TBRACE  15              /* {c-list} */
                   16532: #define        TASYNC  16              /* c & */
                   16533: #define        TFUNCT  17              /* function name { command; } */
                   16534: #define        TTIME   18              /* time pipeline */
                   16535: #define        TEXEC   19              /* fork/exec eval'd TCOM */
                   16536: #define TSELECT        20              /* select */
                   16537: 
                   16538: /*
                   16539:  * prefix codes for words in command tree
                   16540:  */
                   16541: #define        EOS     0               /* end of string */
                   16542: #define        CHAR    1               /* unquoted character */
                   16543: #define        QCHAR   2               /* quoted character */
                   16544: #define        COMSUB  3               /* $() substitution (0 terminated) */
                   16545: #define        OQUOTE  4               /* opening " or ' */
                   16546: #define        CQUOTE  5               /* closing " or ' */
                   16547: #define        OSUBST  6               /* opening ${ substitution */
                   16548: #define        CSUBST  7               /* closing } of above */
                   16549: 
                   16550: /*
                   16551:  * IO redirection
                   16552:  */
                   16553: struct ioword {
                   16554:        int     unit;   /* unit affected */
                   16555:        int     flag;   /* action (below) */
                   16556:        char   *name;   /* file name */
                   16557: };
                   16558: 
                   16559: /* ioword.flag - type of redirection */
                   16560: #define        IOTYPE  0xF             /* type: bits 0:3 */
                   16561: #define        IOREAD  0x1             /* < */
                   16562: #define        IOWRITE 0x2             /* > */
                   16563: #define        IORDWR  0x3             /* <>: todo */
                   16564: #define        IOHERE  0x4             /* << (here file) */
                   16565: #define        IOCAT   0x5             /* >> */
                   16566: #define        IODUP   0x6             /* <&/>& */
                   16567: #define        IOEVAL  BIT(4)          /* expand in << */
                   16568: #define        IOSKIP  BIT(5)          /* <<-, skip ^\t* */
                   16569: #define        IOCLOB  BIT(6)          /* >!, override -o noclob */
                   16570: 
                   16571: /* values for E_LOOP longjmp */
                   16572: #define        LBREAK  1
                   16573: #define        LCONTIN 2
                   16574: 
                   16575: /* execute/exchild flags */
                   16576: #define        XEXEC   BIT(0)          /* execute without forking */
                   16577: #define        XFORK   BIT(5)          /* fork before executing */
                   16578: #define        XBGND   BIT(1)          /* command & */
                   16579: #define        XPIPEI  BIT(2)          /* input is pipe */
                   16580: #define        XPIPEO  BIT(3)          /* output is pipe */
                   16581: #define        XPIPE   (XPIPEI|XPIPEO) /* member of pipe */
                   16582: #define        XXCOM   BIT(4)          /* dup2 xcomfd to 1 */
                   16583: #define XXWHL  BIT(6)          /* don't flush stdin before fork */
                   16584: 
                   16585: /*
                   16586:  * flags to control expansion of words
                   16587:  */
                   16588: #define        DOBLANK BIT(1)          /* perform blank interpretation */
                   16589: #define        DOGLOB  BIT(2)          /* expand [?* */
                   16590: #define        DOPAT   BIT(3)          /* quote *?[ */
                   16591: #define        DOTILDE BIT(5)          /* expand ~ */
                   16592: 
                   16593: #if 0
                   16594: /* job.c: job control primatives */
                   16595: int    execute ARGS((struct op *, int flags)); /* execute tree */
                   16596: int    exchild ARGS((struct op *, int flags)); /* execute tree as child */
                   16597: int    waitfor ARGS((int job));                /* wait for job completion */
                   16598: int    waitlast ARGS((void));                  /* wait for last job */
                   16599: 
                   16600: /* eval.c: word expansion */
                   16601: char  **eval ARGS((char **wv, int flag));      /* expand words */
                   16602: char   *evalstr ARGS((char *wp, int flags));   /* expand word */
                   16603: char   *substitute ARGS((const char *s, int flags)); /* compile and expand string */
                   16604: 
                   16605: /* tree.c: command trees */
                   16606: void   ptree ARGS((struct op *t, FILE *f));    /* print tree */
                   16607: char   *wdscan ARGS((char *wp, int c));                /* scan word for prefix */
                   16608: char   *wdcopy ARGS((char *wp, Area *));       /* copy word */
                   16609: struct op *tcopy ARGS((struct op *t, Area *)); /* copy tree */
                   16610: void   tfree ARGS((struct op *t, Area *));     /* free tree */
                   16611: #endif
                   16612: ./pdksh/sh/Changes   644    653   1762        1124  5243742770  11316 0ustar  hluFix echo $$ | cat
                   16613: #if and config option cleanup
                   16614: Fix let evaluation of null/unset vars
                   16615: alloc improvement
                   16616: Fix accidental SCCS keywords
                   16617: Fix Xstring overwriting in lex.c
                   16618: Print here doc temp file when printing I/O actions
                   16619: Add more slack on end of Xstrings
                   16620: Fix up test(1) parsing
                   16621: Run shell scripts with EXECSHELL
                   16622: Make temp files 0600
                   16623: Make unset -f work
                   16624: Make trailing blank or tab in alias work
                   16625: Fix command completion bug
                   16626: --------------------------------------------------
                   16627: Fix "cd / foo"
                   16628: Fix getopts accidentally resetting itself
                   16629: --------------------------------------------------
                   16630: Fix whence exit codes
                   16631: ./pdksh/sh/config.h   644    653   1762        4140  5302767335  11442 0ustar  hlu/*
                   16632:  * Configuration file for the PD ksh
                   16633:  *
                   16634:  * RCSid: $Id: config.h,v 1.5 1992/08/12 14:15:22 sjg Exp $
                   16635:  */
                   16636: 
                   16637: #ifndef        _CONFIG_H
                   16638: #define        _CONFIG_H
                   16639: 
                   16640: /*
                   16641:  * Builtin edit modes
                   16642:  */
                   16643: 
                   16644: #define        EMACS                           /* EMACS-like mode */
                   16645: #define        VI                              /* vi-like mode */
                   16646: #define        JOBS                            /* job control */
                   16647: 
                   16648: #ifndef SIGINT
                   16649: #include <signal.h>
                   16650: #endif
                   16651: 
                   16652: /*
                   16653:  * leave USE_SIGACT defined.
                   16654:  * if you don't have sigaction(2) and the
                   16655:  * implementation in sigact.c doesn't work for your system,
                   16656:  * fix it.
                   16657:  * 
                   16658:  * Of course if your system has a real sigaction() 
                   16659:  * implementation that is faulty! undef JOBS and add USE_SIGNAL
                   16660:  * or whatever does work.  You may find it necessary to undef
                   16661:  * USE_SIGACT, if so please report it.
                   16662:  */
                   16663: #define USE_SIGACT                     /* POSIX signal handling */
                   16664: /* 
                   16665:  * These control how sigact.c implements sigaction()
                   16666:  * If you don't define any of them it will try and work it out 
                   16667:  * for itself.  The are listed in order of preference (usefulness).
                   16668:  */
                   16669: #if 0
                   16670: #define USE_SIGMASK                    /* BSD4.2 ? signal handling */
                   16671: #define USE_SIGSET                     /* BSD4.1 ? signal handling */
                   16672: #define USE_SIGNAL                     /* plain old signal(2) */
                   16673: #endif
                   16674: 
                   16675: #if defined(JOBS) && (!defined(SIGCONT) || (defined(_SYSV) && defined(USE_SIGNAL)))
                   16676: #undef JOBS
                   16677: #endif
                   16678: 
                   16679: #if 0
                   16680: #define        FASCIST                 /* Fascist getopts */
                   16681: #endif
                   16682: #define        SHARPBANG                       /* Hack to handle #! */
                   16683: #if 0
                   16684: #define        SILLY                   /* Game of life in EMACS mode */
                   16685: #define        SWTCH                   /* Handle SWTCH for shl(1) */
                   16686: #endif
                   16687: 
                   16688: /*
                   16689:  * better to leave this one out, and let users that
                   16690:  * like it add
                   16691:  *   bind '^[^['=complete-list
                   16692:  * to their .kshrc
                   16693:  */
                   16694: #if 0
                   16695: #define COMPLETE_LIST                  /* default to Emacs style completion */
                   16696: #endif
                   16697: /*
                   16698:  * ALTERNATIONS is csh not ksh, but it is such a nice feature...
                   16699:  */
                   16700: #define ALTERNATIONS                   /* csh {a,b,c} arg expansion */
                   16701: 
                   16702: #if 0
                   16703: #define COMPLEX_HISTORY                        /* Peter Collinson's history */
                   16704: #endif
                   16705: /*
                   16706:  * if you don't have mmap() you can't use Peter Collinson's history
                   16707:  * mechanism.  If that is the case, then define EASY_HISTORY
                   16708:  */
                   16709: #if !defined(COMPLEX_HISTORY) || defined(NO_MMAP)
                   16710: # undef COMPLEX_HISTORY
                   16711: # ifndef EASY_HISTORY
                   16712: #  define EASY_HISTORY                 /* sjg's trivial history file */
                   16713: # endif
                   16714: #endif
                   16715:   
                   16716: #endif /* _CONFIG_H */
                   16717: ./pdksh/sh/tty.h   644    653   1762        1321  5243743667  11021 0ustar  hlu/*
                   16718:        tty.h -- centralized definitions for a variety of terminal interfaces
                   16719: 
                   16720:        created by DPK, Oct. 1986
                   16721: 
                   16722:        last edit:      30-Jul-1987     D A Gwyn
                   16723: */
                   16724: 
                   16725: #if _BSD_SYSV                  /* BRL UNIX System V emulation */
                   16726: #include <termio.h>    /* includes <sys/_ioctl.h> */
                   16727: #ifndef NTTYDISC
                   16728: #define        TIOCGETD        _IOR( 't', 0, int )
                   16729: #define        TIOCSETD        _IOW( 't', 1, int )
                   16730: #define        NTTYDISC        2
                   16731: #endif
                   16732: #ifndef TIOCSTI
                   16733: #define        TIOCSTI         _IOW( 't', 114, char )
                   16734: #endif
                   16735: #ifndef TIOCSPGRP
                   16736: #define        TIOCSPGRP       _IOW( 't', 118, int )
                   16737: #endif
                   16738: #else  /* !_BSD_SYSV */
                   16739: #if _BSD
                   16740: #ifdef _MINIX
                   16741: #include <sgtty.h>
                   16742: #define TIOCSETN       TIOCSETP
                   16743: #else
                   16744: #include <sys/ioctl.h>
                   16745: #endif
                   16746: #else
                   16747: #ifdef _POSIX_TERM
                   16748: #include <termios.h>
                   16749: #else
                   16750: #include <termio.h>
                   16751: #endif
                   16752: #endif
                   16753: #endif /* _BSD_SYSV */
                   16754: ./pdksh/sh/version.c   644    653   1762        2302  5243743701  11646 0ustar  hlu/*
                   16755:  * value of $KSH_VERSION
                   16756:  */
                   16757: 
                   16758: #ifndef lint
                   16759: static char *RCSid = "$Id: version.c,v 1.6 1992/08/12 14:15:53 sjg Exp $";
                   16760: #endif
                   16761: 
                   16762: #include "stdh.h"
                   16763: #include <setjmp.h>
                   16764: #include "sh.h"
                   16765: #include "patchlevel.h"
                   16766: 
                   16767: char ksh_version [] =
                   16768:        "KSH_VERSION=@(#)PD KSH v4.7 92/08/12";
                   16769: 
                   16770: /***
                   16771: $Log: version.c,v $
                   16772:  * Revision 1.6  1992/08/12  14:15:53  sjg
                   16773:  * Patch07: fix some build problems,
                   16774:  * and avoid core dump from arg processing bug.
                   16775:  *
                   16776:  * Revision 1.5  1992/08/10  12:03:29  sjg
                   16777:  * Update for patch06.
                   16778:  * Contributions from Peter Collinson, Neil Smithline and sjg
                   16779:  *
                   16780:  * Revision 1.4  1992/05/12  09:30:37  sjg
                   16781:  * see ChangeLog
                   16782:  *
                   16783:  * Revision 1.3  1992/05/03  08:29:20  sjg
                   16784:  * Update for Patch05
                   16785:  *
                   16786:  * Revision 1.2  1992/04/25  08:33:28  sjg
                   16787:  * Added RCS key.
                   16788:  *
                   16789:  * Revision 1.1  1992/04/18  05:51:48  sjg
                   16790:  * Initial revision
                   16791:  *
                   16792: Version  4.0  91/11/09  sjg
                   16793: distribution
                   16794: Revision 3.3  89/03/27  15:52:29  egisin
                   16795: distribution
                   16796: 
                   16797: Revision 3.2  88/12/14  20:10:41  egisin
                   16798: many fixes
                   16799: 
                   16800: Revision 3.1  88/11/03  09:18:36  egisin
                   16801: alpha distribution
                   16802: 
                   16803: Revision 1.3  88/10/20  17:34:03  egisin
                   16804: added @(#) to ksh_version
                   16805: 
                   16806: Revision 1.2  88/09/27  19:01:58  egisin
                   16807: fix version.c
                   16808: 
                   16809: Revision 1.1  88/09/27  18:59:06  egisin
                   16810: Initial revision
                   16811: ***/
                   16812: 
                   16813: ./pdksh/sh/stdh.h   644    653   1762        3543  5302634075  11137 0ustar  hlu/* NAME:
                   16814:  *      stdh.h - standard headers
                   16815:  *
                   16816:  * SYNOPSIS:
                   16817:  *      #include "stdh.h"
                   16818:  *
                   16819:  * DESCRIPTION:
                   16820:  *      We use this header to encapsulate all the stddef et al 
                   16821:  *      inclusion so that most of the source can ignore the 
                   16822:  *      problems that their lack might cause.
                   16823:  *
                   16824:  * SEE ALSO:
                   16825:  *      
                   16826:  *
                   16827:  * AMENDED:
                   16828:  *      91/11/25  13:33:12  (sjg)
                   16829:  *
                   16830:  * RELEASED:
                   16831:  *      91/11/25  13:33:17  v1.3
                   16832:  *
                   16833:  * SCCSID:
                   16834:  *      @(#)stdh.h  1.3  91/11/25  13:33:12  (sjg)
                   16835:  *
                   16836:  */
                   16837: 
                   16838: #ifndef ARGS
                   16839: # ifdef __STDC__
                   16840: #   define ARGS(args) args
                   16841: # else
                   16842: #   define ARGS(args) ()
                   16843: #   ifdef VOID
                   16844: #     define void VOID
                   16845: #   endif
                   16846: #   define const
                   16847: #   define volatile
                   16848: # endif
                   16849: #endif
                   16850: 
                   16851: #include <stdio.h>
                   16852: /* if we have std headers then include them here
                   16853:  * otherwise make allowances
                   16854:  */
                   16855: #ifdef linux
                   16856: extern void setfileno ARGS ((FILE *__fp, int __fd));
                   16857: #endif
                   16858: 
                   16859: #ifndef NOSTDHDRS
                   16860: # include <stddef.h>
                   16861: # include <stdlib.h>
                   16862: # include <string.h>
                   16863: # include <memory.h>
                   16864: # include <sys/types.h>
                   16865: #else
                   16866: # ifdef HAVE_SYS_STDTYPES
                   16867: #   include <sys/stdtypes.h>
                   16868: # else
                   16869: #   include <sys/types.h>
                   16870: /* just in case they have sys/stdtypes and don't know it
                   16871:  */
                   16872: #   ifndef     __sys_stdtypes_h
                   16873: #define _PID_T
                   16874: #define _CLOCK_T
                   16875: typedef int pid_t;
                   16876: typedef long clock_t;
                   16877: #   endif
                   16878: # endif
                   16879: # ifdef _SYSV
                   16880: #   include <string.h>
                   16881: # else
                   16882: #   include <strings.h>
                   16883: #   define strchr index
                   16884: #   define strrchr rindex
                   16885: # endif
                   16886: /* just a useful subset of what stdlib.h would have
                   16887:  */
                   16888: extern char * getenv  ARGS((const char *));
                   16889: extern void * malloc  ARGS((size_t));
                   16890: extern int    free    ARGS((void *));
                   16891: extern int    exit    ARGS((int));
                   16892: 
                   16893: /* these _should_ match ANSI */
                   16894: extern char * strstr  ARGS((const char *, const char *));
                   16895: extern void * memmove ARGS((void *, const void *, size_t));
                   16896: extern void * memcpy  ARGS((void *, const void *, size_t));
                   16897: #endif /* NOSTDHDRS */
                   16898:   
                   16899: 
                   16900: #ifndef offsetof
                   16901: #define        offsetof(type,id) ((size_t)&((type*)NULL)->id)
                   16902: #endif
                   16903: 
                   16904: ./pdksh/sh/do_ulimit.c   644    653   1762        5523  5302641624  12153 0ustar  hlu/*
                   16905:        ulimit -- handle "ulimit" builtin
                   16906: 
                   16907:        Eric Gisin, September 1988
                   16908:        Adapted to PD KornShell. Removed AT&T code.
                   16909: 
                   16910:        last edit:      06-Jun-1987     D A Gwyn
                   16911: 
                   16912:        This started out as the BRL UNIX System V system call emulation
                   16913:        for 4.nBSD, and was later extended by Doug Kingston to handle
                   16914:        the extended 4.nBSD resource limits.  It now includes the code
                   16915:        that was originally under case SYSULIMIT in source file "xec.c".
                   16916: */
                   16917: 
                   16918: #ifndef lint
                   16919: static char *RCSid = "$Id: do_ulimit.c,v 1.3 1992/08/10 12:02:23 sjg Exp $";
                   16920: #endif
                   16921: 
                   16922: #if defined(_BSDI) || defined(linux)
                   16923: #define _BSD   1
                   16924: #endif
                   16925: 
                   16926: #include "stdh.h"
                   16927: #include <errno.h>
                   16928: #include <signal.h>
                   16929: #include <setjmp.h>
                   16930: #if defined(_BSD) || defined(_BSD_SYSV)
                   16931: #include <sys/time.h>
                   16932: #include <sys/resource.h>
                   16933: #else
                   16934: #define        RLIMIT_FSIZE    2
                   16935: #endif
                   16936: #include "sh.h"
                   16937: 
                   16938: #ifndef _BSD
                   16939: extern long ulimit();
                   16940: #endif
                   16941: 
                   16942: int
                   16943: do_ulimit(a1, a2)
                   16944:        char    *a1, *a2;
                   16945: {
                   16946:        register int    c;
                   16947:        long            i;
                   16948: #if defined(_BSD) || defined(_BSD_SYSV)
                   16949:        struct rlimit   limit;          /* data being gotten/set */
                   16950:        int             softonly = 0;   /* set => soft limit, clear => hard limit */
                   16951:        int             factor = 1024;  /* unit scaling (1K or 1) */
                   16952: #endif
                   16953:        int     command = RLIMIT_FSIZE;
                   16954: 
                   16955:        if (a1 && (*a1 == '-'))         /* DAG -- Gould added first test */
                   16956:        {       c = *++a1;              /* DAG */
                   16957: #if defined(_BSD) || defined(_BSD_SYSV)
                   16958:                if (c >= 'A' && c <= 'Z')
                   16959:                {
                   16960:                        ++softonly;
                   16961:                        c += 'a' - 'A'; /* DAG -- map to lower-case */
                   16962:                }
                   16963: #endif
                   16964:                switch(c)
                   16965:                {
                   16966: #if defined(_BSD) || defined(_BSD_SYSV)
                   16967:                        case 'c':
                   16968:                                command = RLIMIT_CORE;
                   16969:                                break;
                   16970:                        case 'd':
                   16971:                                command = RLIMIT_DATA;
                   16972:                                break;
                   16973:                        case 'm':
                   16974:                                command = RLIMIT_RSS;
                   16975:                                break;
                   16976:                        case 's':
                   16977:                                command = RLIMIT_STACK;
                   16978:                                break;
                   16979:                        case 't':
                   16980:                                factor = 1;
                   16981:                                command = RLIMIT_CPU;
                   16982:                                break;
                   16983: #endif /* _BSD || _BSD_SYSV */
                   16984:                        case 'f':
                   16985:                                command = RLIMIT_FSIZE;
                   16986: #if _BSD_SYSV
                   16987:                                factor = 512;
                   16988: #endif
                   16989:                                break;
                   16990:                        default:
                   16991: #if _BSD
                   16992:                                errorf("Usage: %s [-cdmstf] [limit]\n", "ulimit");
                   16993: #else
                   16994:                                errorf("Usage: %s [-f] [limit]\n", "ulimit");
                   16995: #endif
                   16996:                }
                   16997:                a1 = a2;
                   16998:        }
                   16999:        if (a1)
                   17000:        {
                   17001:                i = 0;
                   17002:                while ((c = *a1++) >= '0' && c <= '9')
                   17003:                {
                   17004:                        i = (i * 10) + (long)(c - '0');
                   17005:                        if (i < 0)
                   17006:                                goto Error;
                   17007:                }
                   17008:                if (c || i < 0)
                   17009:                        goto Error;
                   17010:        }
                   17011: #if !(defined(_BSD) || defined(_BSD_SYSV))
                   17012:        else
                   17013:        {
                   17014:                i = -1;
                   17015:                command--;
                   17016:        }
                   17017: 
                   17018:        if ((i = ulimit(command, i)) < 0L)
                   17019:                goto Error;
                   17020: 
                   17021:        if (command != RLIMIT_FSIZE)
                   17022:                shellf("%ld\n", i);
                   17023: #else                                  /* DPK -- generalized for 4.nBSD: */
                   17024:        if (getrlimit(command, &limit))
                   17025:                goto Error;     /* errno is already set */
                   17026: 
                   17027:        if (a1)
                   17028:        {
                   17029:                limit.rlim_cur = i * factor;
                   17030: 
                   17031:                if (!softonly)
                   17032:                        limit.rlim_max = limit.rlim_cur;
                   17033: 
                   17034:                if (setrlimit(command, &limit))
                   17035:                        goto Error;
                   17036:        }
                   17037:        else
                   17038:        {
                   17039:                i = softonly ? limit.rlim_cur : limit.rlim_max;
                   17040: #if _BSD                       /* DAG -- System V always prints an integer */
                   17041:                if (i == RLIM_INFINITY)
                   17042:                        shellf("unlimited\n");
                   17043:                else
                   17044: #endif
                   17045:                        shellf("%ld\n", i/factor);
                   17046:        }
                   17047: #endif /* _BSD || _BSD_SYSV */
                   17048:        return 0;
                   17049: 
                   17050:   Error:
                   17051:        errorf("bad ulimit\n");
                   17052: }
                   17053: 
                   17054: ./pdksh/sh/patchlevel.h   644    653   1762         162  5243743700  12276 0ustar  hlu/*
                   17055:  * PD KSH
                   17056:  * $Id: patchlevel.h,v 4.7 1992/08/12 14:15:45 sjg Exp $
                   17057:  */
                   17058: #define VERSION                4
                   17059: #define PATCHLEVEL     7
                   17060: ./pdksh/sh/proto.h   644    653   1762       20022  5243743663  11357 0ustar  hlu/*
                   17061:  * prototypes for PD-KSH
                   17062:  * originally generated using "cproto.c 3.5 92/04/11 19:28:01 cthuang "
                   17063:  * $Id: proto.h,v 1.2 1992/08/10 12:03:05 sjg Exp $
                   17064:  */
                   17065: #ifndef ARGS
                   17066: #if defined(__STDC__) || defined(__cplusplus)
                   17067: #define ARGS(s) s
                   17068: #else
                   17069: #define ARGS(s) ()
                   17070: #endif
                   17071: #endif
                   17072: 
                   17073: /* alloc.c */
                   17074: Area * ainit            ARGS((Area *ap));
                   17075: void   afreeall         ARGS((Area *ap));
                   17076: void * alloc            ARGS((size_t size, Area *ap));
                   17077: void * aresize          ARGS((void *ptr, size_t size, Area *ap));
                   17078: void   afree            ARGS((void *ptr, Area *ap));
                   17079: /* c_ksh.c */
                   17080: int    c_hash           ARGS((char **wp));
                   17081: int    c_cd             ARGS((char **wp));
                   17082: int    c_print          ARGS((char **wp));
                   17083: int    c_whence         ARGS((char **wp));
                   17084: int    c_typeset        ARGS((char **wp));
                   17085: int    c_alias          ARGS((char **wp));
                   17086: int    c_unalias        ARGS((char **wp));
                   17087: int    c_let            ARGS((char **wp));
                   17088: int    c_jobs           ARGS((char **wp));
                   17089: int    c_fgbg           ARGS((char **wp));
                   17090: int    c_kill           ARGS((char **wp));
                   17091: int    c_bind           ARGS((char **wp));
                   17092: /* c_sh.c */
                   17093: int    c_label          ARGS((char **wp));
                   17094: int    c_shift          ARGS((char **wp));
                   17095: int    c_umask          ARGS((char **wp));
                   17096: int    c_dot            ARGS((char **wp));
                   17097: int    c_wait           ARGS((char **wp));
                   17098: int    c_read           ARGS((char **wp));
                   17099: int    c_eval           ARGS((char **wp));
                   17100: int    c_trap           ARGS((char **wp));
                   17101: void   setsig           ARGS((struct trap *p, void (*f)()));
                   17102: int    c_return         ARGS((char **wp));
                   17103: int    c_brkcont        ARGS((char **wp));
                   17104: int    c_exit           ARGS((char **wp));
                   17105: int    c_set            ARGS((char **wp));
                   17106: int    c_unset          ARGS((char **wp));
                   17107: int    c_ulimit         ARGS((char **wp));
                   17108: int    c_times          ARGS((char **wp));
                   17109: int    timex            ARGS((struct op *t, int f));
                   17110: int    c_exec           ARGS((char **wp));
                   17111: int    c_builtin        ARGS((char **wp));
                   17112: /* c_test.c */
                   17113: int    c_test           ARGS((char **wp));
                   17114: int    oexpr            ARGS((int n));
                   17115: int    aexpr            ARGS((int n));
                   17116: int    nexpr            ARGS((int n));
                   17117: int    primary          ARGS((int n));
                   17118: int    filstat          ARGS((char *nm, int mode));
                   17119: int    t_lex            ARGS((char *s));
                   17120: int    newerf           ARGS((char *f1, char *f2));
                   17121: int    olderf           ARGS((char *f1, char *f2));
                   17122: int    equalf           ARGS((char *f1, char *f2));
                   17123: /* do_ulimit.c */
                   17124: int    do_ulimit        ARGS((char *a1, char *a2));
                   17125: /* edit.c */
                   17126: int    x_read           ARGS((int fd, char *buf, size_t len));
                   17127: int    x_getc           ARGS((void));
                   17128: void   x_flush          ARGS((void));
                   17129: void   x_adjust         ARGS((void));
                   17130: void   x_putc           ARGS((int c));
                   17131: void   x_puts           ARGS((char *s));
                   17132: void   x_init           ARGS((void));
                   17133: bool_t         x_mode           ARGS((bool_t onoff));
                   17134: int    promptlen        ARGS((char *cp));
                   17135: int    init_editmode    ARGS((void));
                   17136: void   set_editmode     ARGS((char *ed));
                   17137: /* emacs.c */
                   17138: int    x_emacs          ARGS((char *buf, size_t len));
                   17139: void   x_redraw         ARGS((int limit));
                   17140: void   x_bind           ARGS((char *a1, char *a2, int macro));
                   17141: void   x_init_emacs     ARGS((void));
                   17142: void   x_emacs_keys     ARGS((int erase, int kill, int werase, int intr, int quit));
                   17143: char * x_lastcp         ARGS((void));
                   17144: /* eval.c */
                   17145: char * substitute       ARGS((char const *cp, int f));
                   17146: char **        eval             ARGS((char **ap, int f));
                   17147: char * evalstr          ARGS((char *cp, int f));
                   17148: char * evalonestr       ARGS((char *cp, int f));
                   17149: /* exec.c */
                   17150: int    execute          ARGS((struct op *t, volatile int flags));
                   17151: int    shcomexec        ARGS((char **wp));
                   17152: int    define           ARGS((char *name, struct op *t));
                   17153: int    builtin          ARGS((char *name, int (*func)()));
                   17154: struct tbl *   findcom  ARGS((char *name, int insert));
                   17155: int    flushcom         ARGS((int all));
                   17156: char * search           ARGS((char *name, char *path, int mode));
                   17157: int    pr_menu          ARGS((char **ap, int usestored));
                   17158: /* expr.c */
                   17159: void   evalerr          ARGS((char *err));
                   17160: long   evaluate         ARGS((const char *expr));
                   17161: /* getopts.c */
                   17162: void   resetopts        ARGS((void));
                   17163: int    c_getopts        ARGS((char **wp));
                   17164: /* history.c */
                   17165: int    c_fc             ARGS((register char **wp));
                   17166: void   histbackup       ARGS((void));
                   17167: #ifdef EASY_HISTORY
                   17168: void   histsave         ARGS((char *cmd));
                   17169: #else
                   17170: void   sethistsize      ARGS((int n));
                   17171: void   sethistfile      ARGS((char *name));
                   17172: void   histsave         ARGS((int lno, char *cmd, int dowrite));
                   17173: #endif
                   17174: char **        histget          ARGS((char *str));
                   17175: char * histrpl          ARGS((char *s, char *pat, char *rep, int global));
                   17176: void   hist_init        ARGS((Source *s));
                   17177: void   hist_finish      ARGS((void));
                   17178: char **        histpos          ARGS((void));
                   17179: int    histN            ARGS((void));
                   17180: int    histnum          ARGS((int n));
                   17181: char * findhist         ARGS((int start, int fwd, char *str));
                   17182: /* io.c */
                   17183: int    errorf           ARGS((const char *fmt, ...));
                   17184: int    shellf           ARGS((const char *fmt, ...));
                   17185: void   fopenshf         ARGS((int fd));
                   17186: void   flushshf         ARGS((int fd));
                   17187: int    savefd           ARGS((int fd));
                   17188: void   restfd           ARGS((int fd, int ofd));
                   17189: void   openpipe         ARGS((int *pv));
                   17190: void   closepipe        ARGS((int *pv));
                   17191: struct temp *  maketemp ARGS((Area *ap));
                   17192: /* jobs.c */
                   17193: void   j_init           ARGS((void));
                   17194: void   j_exit           ARGS((void));
                   17195: void   j_change         ARGS((void));
                   17196: int    exchild          ARGS((struct op *t, int flags));
                   17197: int    waitlast         ARGS((void));
                   17198: int    j_reapchld       ARGS((void));
                   17199: int    j_reap           ARGS((void));
                   17200: int    waitfor          ARGS((int job));
                   17201: void   j_kill           ARGS((int job, int sig));
                   17202: int    j_resume         ARGS((int job, int bg));
                   17203: void   j_jobs           ARGS((void));
                   17204: void   j_notify         ARGS((void));
                   17205: int    j_lookup         ARGS((char *cp));
                   17206: int    j_stopped        ARGS((void));
                   17207: /* lex.c */
                   17208: int    yylex            ARGS((int cf));
                   17209: int    gethere          ARGS((void));
                   17210: void   yyerror          ARGS((const char *msg));
                   17211: Source * pushs          ARGS((int type));
                   17212: int    pprompt          ARGS((char *cp));
                   17213: /* mail.c */
                   17214: void   mcheck           ARGS((void));
                   17215: void   mbset            ARGS((char *p));
                   17216: void   mpset            ARGS((char *mptoparse));
                   17217: void   mprint           ARGS((void));
                   17218: /* main.c */
                   17219: int    main             ARGS((int argc, char **argv, char **envp));
                   17220: int    include          ARGS((char *name));
                   17221: #if 0
                   17222: int    command          ARGS((char *comm));
                   17223: #endif
                   17224: int    shell            ARGS((Source *s));
                   17225: void   leave            ARGS((int rv));
                   17226: int    error            ARGS((void));
                   17227: int    unwind           ARGS((void));
                   17228: int    newenv           ARGS((int type));
                   17229: int    quitenv          ARGS((void));
                   17230: void   aerror           ARGS((Area *ap, const char *msg));
                   17231: /* misc.c */
                   17232: void   setctypes        ARGS((/* const */ char *s, int t));
                   17233: void   initctypes       ARGS((void));
                   17234: char * ulton            ARGS((unsigned long n, int base));
                   17235: char * strsave          ARGS((char *s, Area *ap));
                   17236: int    option           ARGS((const char *n));
                   17237: char * getoptions       ARGS((void));
                   17238: void   printoptions     ARGS((void));
                   17239: int    getn             ARGS((char *as));
                   17240: char * strerror         ARGS((int i));
                   17241: int    gmatch           ARGS((char *s, char *p));
                   17242: void   qsortp           ARGS((void **base, size_t n, int (*f)()));
                   17243: int    qsort1           ARGS((void **base, void **lim, int (*f)()));
                   17244: int    xstrcmp          ARGS((void *p1, void *p2));
                   17245: void   cleanpath        ARGS((char *pwd, char *dir, char *clean));
                   17246: /* syn.c */
                   17247: int    yyparse          ARGS((void));
                   17248: int    keywords         ARGS((void));
                   17249: struct op * compile     ARGS((Source *s));
                   17250: /* table.c */
                   17251: unsigned int   hash     ARGS((char *n));
                   17252: void   tinit            ARGS((struct table *tp, Area *ap));
                   17253: struct tbl *   tsearch  ARGS((struct table *tp, char *n, unsigned int h));
                   17254: struct tbl *   tenter   ARGS((struct table *tp, char *n, unsigned int h));
                   17255: void   tdelete          ARGS((struct tbl *p));
                   17256: void   twalk            ARGS((struct table *tp));
                   17257: struct tbl *   tnext    ARGS((void));
                   17258: struct tbl **  tsort    ARGS((struct table *tp));
                   17259: /* trace.c */
                   17260: /* trap.c */
                   17261: Trap * gettrap          ARGS((char *name));
                   17262: void   trapsig          ARGS((int i));
                   17263: int    runtraps         ARGS((void));
                   17264: int    runtrap          ARGS((Trap *p));
                   17265: int    cleartraps       ARGS((void));
                   17266: int    ignoresig        ARGS((int i));
                   17267: int    restoresigs      ARGS((void));
                   17268: /* tree.c */
                   17269: void   ptree            ARGS((struct op *t, FILE *f));
                   17270: int    pioact           ARGS((FILE *f, struct ioword *iop));
                   17271: int    fptreef          ARGS((FILE *f, char *fmt, ...));
                   17272: int    snptreef         ARGS((char *s, int n, char *fmt, ...));
                   17273: struct op *    tcopy    ARGS((struct op *t, Area *ap));
                   17274: char * wdcopy           ARGS((char *wp, Area *ap));
                   17275: char * wdscan           ARGS((char *wp, int c));
                   17276: void   tfree            ARGS((struct op *t, Area *ap));
                   17277: /* var.c */
                   17278: void   newblock         ARGS((void));
                   17279: void   popblock         ARGS((void));
                   17280: struct tbl *   global   ARGS((char *n));
                   17281: struct tbl *   local    ARGS((char *n));
                   17282: char * strval           ARGS((struct tbl *vp));
                   17283: long   intval           ARGS((struct tbl *vp));
                   17284: void   setstr           ARGS((struct tbl *vq, char *s));
                   17285: struct tbl *   strint   ARGS((struct tbl *vq, struct tbl *vp));
                   17286: void   setint           ARGS((struct tbl *vq, long n));
                   17287: int    import           ARGS((char *thing));
                   17288: struct tbl *   typeset  ARGS((char *var, int set, int clr));
                   17289: void   unset            ARGS((struct tbl *vp));
                   17290: int    isassign         ARGS((char *s));
                   17291: char **        makenv           ARGS((void));
                   17292: /* version.c */
                   17293: /* vi.c */
                   17294: void   vi_reset         ARGS((char *buf, int len));
                   17295: int    vi_hook          ARGS((int ch));
                   17296: int    save_cbuf        ARGS((void));
                   17297: int    restore_cbuf     ARGS((void));
                   17298: int    x_vi             ARGS((char *buf, size_t len));
                   17299: int    getch            ARGS((void));
                   17300: char **        globstr          ARGS((char *stuff));
                   17301: 
                   17302: 
                   17303: ./pdksh/sh/sigact.h   644    653   1762        3662  5243743611  11452 0ustar  hlu/* NAME:
                   17304:  *      sigact.h - sigaction et al
                   17305:  *
                   17306:  * SYNOPSIS:
                   17307:  *      #include <signal.h>
                   17308:  *      #ifndef  SA_NOCLDSTOP
                   17309:  *      # include "sigact.h"
                   17310:  *      #endif
                   17311:  *
                   17312:  * DESCRIPTION:
                   17313:  *      This header is the interface to a fake sigaction(2) implementation.  
                   17314:  *      Do NOT include this header unless your system does not 
                   17315:  *      have a real sigaction(2) implementation.
                   17316:  */
                   17317: /*
                   17318:  * $Log: sigact.h,v $
                   17319:  * Revision 1.2  1992/04/24  15:04:11  sjg
                   17320:  * now compiles with cc
                   17321:  *
                   17322:  * Revision 1.1  1992/04/24  12:01:38  sjg
                   17323:  * Initial revision
                   17324:  *
                   17325:  */
                   17326: 
                   17327: #ifndef _SIGACT_H
                   17328: #define _SIGACT_H
                   17329: 
                   17330: #ifndef ARGS
                   17331: # if defined(__STDC__)
                   17332: #   define ARGS(p) p
                   17333: # else
                   17334: #   define ARGS(p) ()
                   17335: # endif
                   17336: #endif
                   17337: #ifndef __STDC__
                   17338: # define volatile                      /* can change without warning */
                   17339: # define const                         /* read only */
                   17340: #endif
                   17341: 
                   17342: #ifndef SIGKILL
                   17343: # include <signal.h>
                   17344: #endif
                   17345: #ifndef SA_NOCLDSTOP
                   17346: /* sa_flags */
                   17347: #define        SA_NOCLDSTOP    0x0001          /* don't send SIGCHLD on child stop */
                   17348: #define SA_RESTART     0x0002          /* re-start I/O */
                   17349: 
                   17350: /* sigprocmask flags */
                   17351: #define        SIG_BLOCK       0x0001
                   17352: #define        SIG_UNBLOCK     0x0002
                   17353: #define        SIG_SETMASK     0x0004
                   17354: 
                   17355: #ifndef __sys_stdtypes_h
                   17356: typedef int sigset_t;
                   17357: #endif
                   17358: 
                   17359: struct sigaction
                   17360: {
                   17361:   void         (*sa_handler)();
                   17362:   sigset_t     sa_mask;
                   17363:   int          sa_flags;
                   17364: };
                   17365: 
                   17366: 
                   17367: int    sigaction       ARGS(( int sig, struct sigaction *act, struct sigaction *oact ));
                   17368: int    sigaddset       ARGS(( sigset_t *mask, int sig ));
                   17369: int    sigdelset       ARGS(( sigset_t *mask, int sig ));
                   17370: int    sigemptyset     ARGS(( sigset_t *mask ));
                   17371: int    sigfillset      ARGS(( sigset_t *mask ));
                   17372: int    sigismember     ARGS(( sigset_t *mask, int sig ));
                   17373: int    sigpending      ARGS(( sigset_t *set ));
                   17374: int    sigprocmask     ARGS(( int how, sigset_t *set, sigset_t *oldset ));
                   17375: int    sigsuspend      ARGS(( sigset_t *mask ));
                   17376: 
                   17377: #ifndef sigmask
                   17378: #define sigmask(m)     (1<<((m)-1))    /* convert SIGnum to mask */
                   17379: #endif
                   17380: #if !defined(NSIG) && defined(_NSIG)
                   17381: # define NSIG _NSIG
                   17382: #endif
                   17383: #endif /* ! SA_NOCLDSTOP */
                   17384: #endif /* _SIGACT_H */
                   17385: /*
                   17386:  * Local Variables:
                   17387:  * version-control:t
                   17388:  * comment-column:40
                   17389:  * End:
                   17390:  */
                   17391: ./pdksh/sh/sigact.c   644    653   1762       13042  5243743636  11465 0ustar  hlu/* NAME:
                   17392:  *      sigact.c - fake sigaction(2)
                   17393:  *
                   17394:  * SYNOPSIS:
                   17395:  *      #include <signal.h>
                   17396:  *      #ifndef  SA_NOCLDSTOP
                   17397:  *      # include "sigact.h"
                   17398:  *      #endif
                   17399:  * 
                   17400:  *      int sigaction(int sig, struct sigaction *act, 
                   17401:  *                      struct sigaction *oact);
                   17402:  *      int sigaddset(sigset_t *mask, int sig);
                   17403:  *      int sigdelset(sigset_t *mask, int sig);
                   17404:  *      int sigemptyset(sigset_t *mask);
                   17405:  *      int sigfillset(sigset_t *mask);
                   17406:  *      int sigismember(sigset_t *mask, int sig);
                   17407:  *      int sigpending(sigset_t *set);
                   17408:  *      int sigprocmask(int how, sigset_t *set, sigset_t *oldset);
                   17409:  *      int sigsuspend(sigset_t *mask);
                   17410:  *
                   17411:  * DESCRIPTION:
                   17412:  *      This is a fake sigaction implementation.  It uses 
                   17413:  *      sigset(2) if available, otherwise it just uses 
                   17414:  *      signal(2).  If it thinks sigaction(2) really exists it 
                   17415:  *      compiles to almost nothing.
                   17416:  *      
                   17417:  *      The need for all this is the problems caused by mixing 
                   17418:  *      signal handling routines in the one process.  This 
                   17419:  *      module allows for a consistent POSIX compliant interface 
                   17420:  *      to whatever is available.
                   17421:  *
                   17422:  * RETURN VALUE:
                   17423:  *      0==success, -1==failure
                   17424:  *
                   17425:  * FILES:
                   17426:  *      None.
                   17427:  *
                   17428:  * SEE ALSO:
                   17429:  *      
                   17430:  *
                   17431:  * BUGS:
                   17432:  *      Since we fake most of this, don't expect fancy usage to 
                   17433:  *      work.
                   17434:  *      
                   17435:  * COPYRIGHT:
                   17436:  *      @(#)Copyright (c) 1992 Simon J. Gerraty
                   17437:  *
                   17438:  *      This is free software.  It comes with NO WARRANTY.
                   17439:  *      Permission to use, modify and distribute this source code 
                   17440:  *      is granted subject to the following conditions.
                   17441:  *      1/ that that the above copyright notice and this notice 
                   17442:  *      are preserved in all copies and that due credit be given 
                   17443:  *      to the author.  
                   17444:  *      2/ that any changes to this code are clearly commented 
                   17445:  *      as such so that the author does get blamed for bugs 
                   17446:  *      other than his own.
                   17447:  *      
                   17448:  *      Please send copies of changes and bug-fixes to:
                   17449:  *      [email protected]
                   17450:  *
                   17451:  */
                   17452: #ifndef lint
                   17453: static char  *RCSid = "$Id: sigact.c,v 1.5 1992/05/03 08:29:10 sjg Exp $";
                   17454: #endif
                   17455: /*
                   17456:  * $Log: sigact.c,v $
                   17457:  * Revision 1.5  1992/05/03  08:29:10  sjg
                   17458:  * Update for Patch05
                   17459:  *
                   17460:  * Revision 1.4  1992/04/29  06:29:13  sjg
                   17461:  * avoid use of #pragma
                   17462:  *
                   17463:  * Revision 1.3  1992/04/26  11:24:43  sjg
                   17464:  * USE_SIGSET corrected in sigsuspend().
                   17465:  *
                   17466:  * Revision 1.2  1992/04/24  15:04:11  sjg
                   17467:  * now compiles with cc
                   17468:  *
                   17469:  * Revision 1.1  1992/04/24  12:03:58  sjg
                   17470:  * Initial revision
                   17471:  *
                   17472:  */
                   17473: 
                   17474: #include <signal.h>
                   17475: 
                   17476: /*
                   17477:  * some systems have a faulty sigaction() implementation!
                   17478:  * Allow us to bypass it.
                   17479:  */
                   17480: #if !defined(SA_NOCLDSTOP) || defined(USE_SIGNAL) || defined(USE_SIGSET) || defined(USE_SIGMASK)
                   17481: 
                   17482: /*
                   17483:  * if we haven't been told,
                   17484:  * try and guess what we should implement with.
                   17485:  */
                   17486: #if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL)
                   17487: # if defined(sigmask) || defined(BSD) || defined(_BSD) && !defined(BSD41)
                   17488: #   define USE_SIGMASK
                   17489: # else
                   17490: #   ifndef NO_SIGSET
                   17491: #     define USE_SIGSET
                   17492: #   else
                   17493: #     define USE_SIGNAL
                   17494: #   endif
                   17495: # endif
                   17496: #endif
                   17497: /*
                   17498:  * if we still don't know, we're in trouble
                   17499:  */
                   17500: #if !defined(USE_SIGSET) && !defined(USE_SIGMASK) && !defined(USE_SIGNAL)
                   17501: error must know what to implement with
                   17502: #endif
                   17503: 
                   17504: #include "sigact.h"
                   17505: 
                   17506: 
                   17507: 
                   17508: int
                   17509: sigaction(sig, act, oact)
                   17510:   int sig;
                   17511:   struct sigaction *act, *oact;
                   17512: {
                   17513:   void (*oldh)();
                   17514: 
                   17515:   if (act)
                   17516:   {
                   17517: #ifdef USE_SIGSET
                   17518:     oldh = sigset(sig, act->sa_handler);
                   17519: #else
                   17520:     oldh = signal(sig, act->sa_handler);
                   17521: #endif
                   17522:   }
                   17523:   else
                   17524:   {
                   17525:     if (oact)
                   17526:     {      
                   17527: #ifdef USE_SIGSET
                   17528:       oldh = sigset(sig, SIG_IGN);
                   17529: #else
                   17530:       oldh = signal(sig, SIG_IGN);
                   17531: #endif
                   17532:       if (oldh != SIG_IGN)
                   17533:       {
                   17534: #ifdef USE_SIGSET
                   17535:        (void) sigset(sig, oldh);
                   17536: #else
                   17537:        (void) signal(sig, oldh);
                   17538: #endif
                   17539:       }
                   17540:     }
                   17541:   }
                   17542:   if (oact)
                   17543:   {
                   17544:     oact->sa_handler = oldh;
                   17545:   }
                   17546:   return 0;                            /* hey we're faking it */
                   17547: }
                   17548: 
                   17549: int
                   17550: sigaddset(mask, sig)
                   17551:   sigset_t *mask;
                   17552:   int sig;
                   17553: {
                   17554:   *mask |= sigmask(sig);
                   17555:   return 0;
                   17556: }
                   17557: 
                   17558: 
                   17559: int
                   17560: sigdelset(mask, sig)
                   17561:   sigset_t *mask;
                   17562:   int sig;
                   17563: {
                   17564:   *mask &= ~(sigmask(sig));
                   17565:   return 0;
                   17566: }
                   17567: 
                   17568: 
                   17569: int
                   17570: sigemptyset(mask)
                   17571:   sigset_t *mask;
                   17572: {
                   17573:   *mask = 0;
                   17574:   return 0;
                   17575: }
                   17576: 
                   17577: 
                   17578: int
                   17579: sigfillset(mask)
                   17580:   sigset_t *mask;
                   17581: {
                   17582:   *mask = ~0;
                   17583:   return 0;
                   17584: }
                   17585: 
                   17586: 
                   17587: int
                   17588: sigismember(mask, sig)
                   17589:   sigset_t *mask;
                   17590:   int sig;
                   17591: {
                   17592:   return ((*mask) & sigmask(sig));
                   17593: }
                   17594: 
                   17595: 
                   17596: int
                   17597: sigpending(set)
                   17598:   sigset_t *set;
                   17599: {
                   17600:   return 0;
                   17601: }
                   17602: 
                   17603: 
                   17604: int
                   17605: sigprocmask(how, set, oldset)
                   17606:   int how;
                   17607:   sigset_t *set, *oldset;
                   17608: {
                   17609: #ifdef USE_SIGSET
                   17610:   register int i;
                   17611: #endif
                   17612:   sigset_t sm;
                   17613: 
                   17614: #ifdef USE_SIGMASK
                   17615:   sm = sigblock(0);
                   17616: #else
                   17617:   sm = 0;
                   17618: #endif
                   17619:   
                   17620:   if (oldset)
                   17621:     *oldset = sm;      /* dangerous ? */
                   17622:   if (set)
                   17623:   {
                   17624:     switch (how)
                   17625:     {
                   17626:     case SIG_BLOCK:
                   17627:       sm |= *set;
                   17628:       break;
                   17629:     case SIG_UNBLOCK:
                   17630:       sm &= ~(*set);
                   17631:       break;
                   17632:     case SIG_SETMASK:
                   17633:       sm = *set;
                   17634:       break;
                   17635:     }
                   17636: #ifdef USE_SIGMASK
                   17637:     (void) sigsetmask(sm);
                   17638: #else
                   17639: # ifdef USE_SIGSET
                   17640:     for (i = 1; i < NSIG; i++)
                   17641:     {
                   17642:       if (how == SIG_UNBLOCK)
                   17643:       {
                   17644:        if (*set & sigmask(i))
                   17645:          sigrelse(i);
                   17646:       }
                   17647:       else
                   17648:        if (sm & sigmask(i))
                   17649:        {
                   17650:          sighold(i);
                   17651:        }
                   17652:     }
                   17653: # endif
                   17654: #endif
                   17655:   }
                   17656:   return 0;
                   17657: }
                   17658: 
                   17659: 
                   17660: int
                   17661: sigsuspend(mask)
                   17662:   sigset_t *mask;
                   17663: {
                   17664: #ifdef USE_SIGSET
                   17665:   int sig = SIGCHLD;                   /* our default */
                   17666:   
                   17667:   /*
                   17668:    * add as many tests as you think sensible, but
                   17669:    * SIGALRM, and SIGCHLD are probably the most
                   17670:    * common.
                   17671:    */
                   17672:   if (*mask & sigmask(SIGALRM))
                   17673:     sig = SIGALRM;
                   17674:   else
                   17675:     if (*mask & sigmask(SIGPIPE))
                   17676:       sig = SIGPIPE;
                   17677:   sigpause(sig);
                   17678: #else
                   17679: # ifdef USE_SIGMASK
                   17680:   sigpause(mask);
                   17681: # else
                   17682:   pause();
                   17683: # endif
                   17684: #endif
                   17685:   return 0;
                   17686: }
                   17687: 
                   17688: #endif /* ! SA_NOCLDSTOP */
                   17689: 
                   17690: 
                   17691: /* This lot (for GNU-Emacs) goes at the end of the file. */
                   17692: /* 
                   17693:  * Local Variables:
                   17694:  * version-control:t
                   17695:  * comment-column:40
                   17696:  * End:
                   17697:  */
                   17698: ./pdksh/sh/trap.c.new   644    653   1762        7771  5302640172  11730 0ustar  hlu/*
                   17699:  * signal handling
                   17700:  */
                   17701: 
                   17702: #ifndef lint
                   17703: static char *RCSid = "$Id: trap.c,v 1.3 1992/08/10 12:03:15 sjg Exp $";
                   17704: #endif
                   17705: 
                   17706: #include "stdh.h"
                   17707: #include <errno.h>
                   17708: #include <signal.h>
                   17709: #include <setjmp.h>
                   17710: #include "sh.h"
                   17711: 
                   17712: Trap sigtraps [SIGNALS] = {
                   17713:        {0,     "EXIT", "Signal 0"}, /* todo: belongs in e.loc->exit */
                   17714:        {SIGHUP, "HUP", "Hangup"},
                   17715:        {SIGINT, "INT", "Interrupt"},
                   17716:        {SIGQUIT, "QUIT", "Quit"},
                   17717:        {SIGILL, "ILL", "Illegal instruction"},
                   17718:        {SIGTRAP, "TRAP", "Trace trap"},
                   17719: #ifdef SIGABRT
                   17720:        {SIGIOT, "ABRT", "Abort"},
                   17721: #else
                   17722:        {SIGIOT, "IOT", "IOT instruction"},
                   17723: #endif
                   17724: #ifdef SIGEMT
                   17725:        {SIGEMT, "EMT", "EMT trap"},
                   17726: #endif
                   17727:        {SIGFPE, "FPE", "Floating exception"},
                   17728:        {SIGKILL, "KILL", "Killed"},
                   17729: #ifdef SIGUSR1
                   17730:        {SIGUSR1, "USR1", "User defined signal 1"},
                   17731: #endif
                   17732:        {SIGSEGV, "SEGV", "Memory fault"},
                   17733: #ifdef SIGUSR2
                   17734:        {SIGUSR2, "USR2", "User defined signal 2"},
                   17735: #endif
                   17736: #ifdef SIGBUS
                   17737:        {SIGBUS, "BUS", "Bus error"},
                   17738: #endif
                   17739: #ifdef SIGSYS
                   17740:        {SIGSYS, "SYS", "Bad system call"},
                   17741: #endif
                   17742:        {SIGPIPE, "PIPE", "Broken pipe"},
                   17743:        {SIGALRM, "ALRM", "Alarm clock"},
                   17744:        {SIGTERM, "TERM", "Terminated"},
                   17745: #ifdef SIGSTKFLT
                   17746:        {SIGSTKFLT, "STKFLT", "Stack fault"},
                   17747: #endif
                   17748: #ifdef SIGCHLD
                   17749:        {SIGCHLD, "CHLD", "Waiting children"},
                   17750: #else
                   17751:        {SIGCLD, "CLD", "Death of a child"},
                   17752: #endif
                   17753: #ifdef SIGPWR
                   17754:        {SIGPWR, "PWR", "Power-fail restart"},
                   17755: #endif
                   17756: #ifdef SIGTSTP /* todo: need to be more portable */
                   17757:        {SIGTSTP, "TSTP", "Stop"},
                   17758: #endif
                   17759:        {SIGTTIN, "TTIN", "Stop (tty input)"},
                   17760: #ifdef SIGPOLL
                   17761:        {SIGPOLL, "POLL", "Pollable event occured"},
                   17762: #endif
                   17763: #ifdef SIGSTOP
                   17764:        {SIGSTOP, "STOP", "Stop (signal)"},
                   17765: #endif
                   17766: #ifdef SIGTTOU
                   17767:        {SIGTTOU, "TTOU", "Stop (tty output)"},
                   17768: #endif
                   17769: #ifdef SIGCONT
                   17770:        {SIGCONT, "CONT", "Continue"},
                   17771: #endif
                   17772: #if defined(SIGURG) && (SIGURG != SIGPOLL)
                   17773:        {SIGURG, "URG", "Urgent condition"}, /* BSDism */
                   17774: #endif
                   17775: #ifdef SIGWINCH
                   17776:        {SIGWINCH, "WINCH", "Window changed"},
                   17777: #endif
                   17778: };
                   17779: 
                   17780: Trap *
                   17781: gettrap(name)
                   17782:        char *name;
                   17783: {
                   17784:        int i;
                   17785:        register Trap *p;
                   17786: 
                   17787:        if (digit(*name)) {
                   17788:                i = getn(name);
                   17789:                return (0 <= i && i < SIGNALS) ? &sigtraps[getn(name)] : NULL;
                   17790:        }
                   17791: #if 0
                   17792:        if (strcmp("ERR", name) == 0)
                   17793:                return &e.loc->err;
                   17794:        if (strcmp("EXIT", name) == 0)
                   17795:                return &e.loc->exit;
                   17796: #endif
                   17797:        for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
                   17798:                if (p->name != NULL && strcmp(p->name, name) == 0)
                   17799:                        return p;
                   17800:        return NULL;
                   17801: }
                   17802: 
                   17803: /*
                   17804:  * trap signal handler
                   17805:  */
                   17806: void
                   17807: trapsig(i)
                   17808:        int i;
                   17809: {
                   17810:        trap = sigtraps[i].set = 1;
                   17811:        if (i == SIGINT && (e.type == E_PARSE || e.type == E_LOOP))
                   17812:                /* dangerous but necessary to deal with BSD silly signals */
                   17813:                longjmp(e.jbuf, 1);
                   17814: #ifdef USE_SIGACT
                   17815:        sigaction(i, &Sigact_trap, NULL);
                   17816: #else
                   17817:        (void) signal(i, trapsig);
                   17818: #endif
                   17819: }
                   17820: 
                   17821: /*
                   17822:  * run any pending traps
                   17823:  */
                   17824: runtraps()
                   17825: {
                   17826:        int i;
                   17827:        register Trap *p;
                   17828: 
                   17829:        for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
                   17830:                if (p->set)
                   17831:                        runtrap(p);
                   17832:        trap = 0;
                   17833: }
                   17834: 
                   17835: runtrap(p)
                   17836:        Trap *p;
                   17837: {
                   17838:        char *trapstr;
                   17839: 
                   17840:        p->set = 0;
                   17841:        if ((trapstr = p->trap) == NULL)
                   17842:                if (p->signal == SIGINT)
                   17843:                        unwind();       /* return to shell() */
                   17844:                else
                   17845:                        return;
                   17846:        if (p->signal == 0)     /* ??? */
                   17847:                p->trap = 0;
                   17848:        command(trapstr);
                   17849: }
                   17850:  
                   17851: /* restore signals for children */
                   17852: cleartraps()
                   17853: {
                   17854:        int i;
                   17855:        register Trap *p;
                   17856: 
                   17857:        if ((p = sigtraps)->trap != NULL) {     /* Maybe put in exchild() */
                   17858:                afree((void *)p->trap,APERM);   /* Necessary? */
                   17859:                p->trap = NULL;
                   17860:        }
                   17861:        for (i = SIGNALS, p = sigtraps; --i >= 0; p++) {
                   17862:                p->set = 0;
                   17863: #ifdef USE_SIGACT
                   17864:                if (p->ourtrap)
                   17865:                {
                   17866:                  sigaction(p->signal, &Sigact_ign, &Sigact);
                   17867:                  if (Sigact.sa_handler != SIG_IGN)
                   17868:                    sigaction(p->signal, &Sigact_dfl, NULL);
                   17869:                }
                   17870: #else
                   17871:                if (p->ourtrap && signal(p->signal, SIG_IGN) != SIG_IGN)
                   17872:                        (void) signal(p->signal, SIG_DFL);
                   17873: #endif
                   17874:        }
                   17875: }
                   17876: 
                   17877: ignoresig(i)
                   17878:        int i;
                   17879: {
                   17880: #ifdef USE_SIGACT
                   17881:   sigaction(i, &Sigact_ign, &Sigact);
                   17882:   sigemptyset(&Sigact.sa_mask);
                   17883:   Sigact.sa_flags = 0;
                   17884: 
                   17885:   if (Sigact.sa_handler != SIG_IGN)
                   17886:     sigtraps[i].sig_dfl = 1;
                   17887: #else
                   17888:   if (signal(i, SIG_IGN) != SIG_IGN)
                   17889:     sigtraps[i].sig_dfl = 1;
                   17890: #endif
                   17891: }
                   17892: 
                   17893: restoresigs()
                   17894: {
                   17895:        int i;
                   17896:        register Trap *p;
                   17897: 
                   17898:        for (p = sigtraps, i = SIGNALS; --i >= 0; p++)
                   17899:                if (p->sig_dfl) {
                   17900:                        p->sig_dfl = 0;
                   17901: #ifdef USE_SIGACT
                   17902:                        sigaction(p->signal, &Sigact_dfl, NULL);
                   17903: #else
                   17904:                        (void) signal(p->signal, SIG_DFL);
                   17905: #endif
                   17906:                }
                   17907: }
                   17908: 
                   17909: ./pdksh/sh/makefile.linux   644    653   1762       13043  5302764171  12677 0ustar  hlu# PD Bourne/Korn Shell
                   17910: # $Id: Makefile,v 1.3 1992/08/10 12:02:18 sjg Exp $
                   17911: 
                   17912: SHELL = /bin/sh
                   17913: MAKE  = make
                   17914: 
                   17915: LN    = ln -s
                   17916: 
                   17917: # You _can_ build this shell without the ../std tree if your
                   17918: # system provides a sufficiently POSIX environment, or if your
                   17919: # BSD system is a Sun or close.  If not try ../std.
                   17920: 
                   17921: # gcc is good value on most mc68k's and sun386's if nothing else.
                   17922: # if you don't have gcc cc should do
                   17923: # CC=gcc -pipe
                   17924: CC=gcc -V ss-921113 -b i386-linux
                   17925: 
                   17926: # The following are the defintions used (or thereabouts) 
                   17927: # to build ksh without ../std
                   17928: #
                   17929: # sun386 SunOS 4.0.2, sun3 SunOS 4.0.3
                   17930: # CONFIG=-D_BSD
                   17931: # XOPTS=-DNOSTDHDRS
                   17932: # copy these from ../std/stdc or ensure they are in libstdc.a
                   17933: # XOBJS = memmove.o strstr.o 
                   17934: #
                   17935: # sun3  SunOS 4.1.1
                   17936: # CONFIG=-D_BSD
                   17937: # XOPTS=-DNOSTDHDRS
                   17938: # copy these from ../std/stdc or ensure they are in libstdc.a
                   17939: # XOBJS = memmove.o
                   17940: #
                   17941: # sun4c (sparc) SunOS 4.1.1
                   17942: # CC=cc -pipe  # don't use gcc
                   17943: # CONFIG=-D_BSD
                   17944: # XOPTS=-DNOSTDHDRS
                   17945: # copy these from ../std/stdc or ensure they are in libstdc.a
                   17946: # XOBJS = memmove.o
                   17947: #
                   17948: # Bull DPX/2 B.O.S. 2.00.45
                   17949: # CC=gcc -ansi
                   17950: # CONFIG=-D_POSIX_SOURCE
                   17951: # XOPTS=
                   17952: # XOBJS=
                   17953: #
                   17954: # Minix-386 1.5.10 with estdio
                   17955: # CONFIG= -D_BSD -D_MINIX -D_POSIX_SOURCE
                   17956: # XOPTS=
                   17957: # XOBJS=
                   17958: #
                   17959: # BSD/386
                   17960: # CONFIG= -D_BSDI -D_POSIX_TERM -D_POSIX_SOURCE
                   17961: # XOPTS=
                   17962: # XOBJS=
                   17963: 
                   17964: # Linux, mmap () is not complete.
                   17965: CONFIG= -D_SYSV -D_POSIX_TERM -DNO_MMAP
                   17966: #CONFIG= -D_SYSV
                   17967: #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
                   17968: #CONFIG= -D_BSD -DCOMPLEX_HISTORY
                   17969: 
                   17970: 
                   17971: STD=../std
                   17972: INCL=$(STD)/h
                   17973: XINCL=-I$(INCL)
                   17974: LDOPTS=-L$(STD)
                   17975: XOBJS=
                   17976: 
                   17977: # use -O if you trust it :-)
                   17978: DBG=-Wall -O2 -fomit-frame-pointer -s
                   17979: CFLAGS = $(DBG) $(CONFIG) $(XINCL) $(XOPTS)
                   17980: 
                   17981: LDFLAGS = $(DBG) $(LDOPTS)
                   17982: 
                   17983: #COMPATLIBS = -lstdc -lposix
                   17984: #XLIBS = -lc_s
                   17985: #XLIBS = -ldirent
                   17986: LDLIBS = $(COMPATLIBS) $(XLIBS)
                   17987: 
                   17988: HDRS = sh.h table.h expand.h lex.h tree.h tty.h trace.h
                   17989: SRCS1 =        version.c main.c misc.c trap.c alloc.c io.c \
                   17990:        syn.c lex.c edit.c emacs.c vi.c history.c tree.c 
                   17991: SRCS2 =        exec.c jobs.c \
                   17992:        c_sh.c c_ksh.c c_test.c getopts.c do_ulimit.c \
                   17993:        var.c table.c eval.c expr.c mail.c sigact.c trace.c
                   17994: SRCS = Makefile $(HDRS) $(SRCS1) $(SRCS2) 
                   17995: 
                   17996: OBJS = version.o main.o misc.o \
                   17997:        syn.o lex.o edit.o emacs.o vi.o tree.o \
                   17998:        exec.o jobs.o trap.o \
                   17999:        c_sh.o c_ksh.o c_test.o \
                   18000:        do_ulimit.o getopts.o expr.o history.o \
                   18001:        var.o table.o alloc.o io.o eval.o mail.o sigact.o trace.o $(XOBJS)
                   18002: 
                   18003: ksh: $(OBJS) 
                   18004:        $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
                   18005: 
                   18006: clean:
                   18007:        rm -f *.o *.out core
                   18008: 
                   18009: clobber: clean
                   18010:        rm -f ksh
                   18011: 
                   18012: link:
                   18013:        ($(SHELL) ../std/mklinks ../std/h stdh.h)
                   18014:        
                   18015: 
                   18016: depend:
                   18017:        makedepend $(CFLAGS) $(SRCS1) $(SRCS2)
                   18018: 
                   18019: install:
                   18020:        @echo "Try:"
                   18021:        @echo "cp ksh /bin"
                   18022:        @echo "strip /bin/ksh"
                   18023:        @echo "chmod 555 /bin/ksh"
                   18024: 
                   18025: .c.s:
                   18026:        $(CC) $(CFLAGS) -S -o $@ $<
                   18027: 
                   18028: asms: $(OBJS:.o=.s)
                   18029: 
                   18030: 
                   18031: # DO NOT DELETE THIS LINE -- make depend depends on it.
                   18032: # If this runs make out of memory, delete /usr/include lines.
                   18033: alloc.o: alloc.c
                   18034: alloc.o: config.h
                   18035: alloc.o: sh.h
                   18036: alloc.o: stdh.h
                   18037: alloc.o: trace.h
                   18038: c_ksh.o: c_ksh.c
                   18039: c_ksh.o: config.h
                   18040: c_ksh.o: sh.h
                   18041: c_ksh.o: stdh.h
                   18042: c_ksh.o: table.h
                   18043: c_ksh.o: trace.h
                   18044: c_sh.o: c_sh.c
                   18045: c_sh.o: config.h
                   18046: c_sh.o: lex.h
                   18047: c_sh.o: sh.h
                   18048: c_sh.o: stdh.h
                   18049: c_sh.o: table.h
                   18050: c_sh.o: trace.h
                   18051: c_sh.o: tree.h
                   18052: c_test.o: c_test.c
                   18053: c_test.o: config.h
                   18054: c_test.o: sh.h
                   18055: c_test.o: stdh.h
                   18056: c_test.o: trace.h
                   18057: edit.o: config.h
                   18058: edit.o: edit.c
                   18059: edit.o: edit.h
                   18060: edit.o: lex.h
                   18061: edit.o: sh.h
                   18062: edit.o: stdh.h
                   18063: edit.o: trace.h
                   18064: edit.o: tty.h
                   18065: emacs.o: config.h
                   18066: emacs.o: edit.h
                   18067: emacs.o: emacs.c
                   18068: emacs.o: expand.h
                   18069: emacs.o: lex.h
                   18070: emacs.o: sh.h
                   18071: emacs.o: stdh.h
                   18072: emacs.o: table.h
                   18073: emacs.o: trace.h
                   18074: emacs.o: tree.h
                   18075: eval.o: config.h
                   18076: eval.o: eval.c
                   18077: eval.o: expand.h
                   18078: eval.o: lex.h
                   18079: eval.o: sh.h
                   18080: eval.o: stdh.h
                   18081: eval.o: table.h
                   18082: eval.o: trace.h
                   18083: eval.o: tree.h
                   18084: exec.o: config.h
                   18085: exec.o: exec.c
                   18086: exec.o: lex.h
                   18087: exec.o: sh.h
                   18088: exec.o: stdh.h
                   18089: exec.o: table.h
                   18090: exec.o: trace.h
                   18091: exec.o: tree.h
                   18092: expr.o: config.h
                   18093: expr.o: expr.c
                   18094: expr.o: sh.h
                   18095: expr.o: stdh.h
                   18096: expr.o: table.h
                   18097: expr.o: trace.h
                   18098: getopts.o: config.h
                   18099: getopts.o: getopts.c
                   18100: getopts.o: sh.h
                   18101: getopts.o: stdh.h
                   18102: getopts.o: table.h
                   18103: getopts.o: trace.h
                   18104: history.o: config.h
                   18105: history.o: history.c
                   18106: history.o: lex.h
                   18107: history.o: sh.h
                   18108: history.o: stdh.h
                   18109: history.o: trace.h
                   18110: io.o: config.h
                   18111: io.o: io.c
                   18112: io.o: sh.h
                   18113: io.o: stdh.h
                   18114: io.o: trace.h
                   18115: jobs.o: config.h
                   18116: jobs.o: jobs.c
                   18117: jobs.o: sh.h
                   18118: jobs.o: stdh.h
                   18119: jobs.o: trace.h
                   18120: jobs.o: tree.h
                   18121: lex.o: config.h
                   18122: lex.o: expand.h
                   18123: lex.o: lex.c
                   18124: lex.o: lex.h
                   18125: lex.o: sh.h
                   18126: lex.o: stdh.h
                   18127: lex.o: table.h
                   18128: lex.o: trace.h
                   18129: lex.o: tree.h
                   18130: mail.o: config.h
                   18131: mail.o: mail.c
                   18132: mail.o: sh.h
                   18133: mail.o: stdh.h
                   18134: mail.o: table.h
                   18135: mail.o: trace.h
                   18136: main.o: config.h
                   18137: main.o: lex.h
                   18138: main.o: main.c
                   18139: main.o: sh.h
                   18140: main.o: stdh.h
                   18141: main.o: table.h
                   18142: main.o: trace.h
                   18143: main.o: tree.h
                   18144: memmove.o: memmove.c
                   18145: memmove.o: stdh.h
                   18146: misc.o: config.h
                   18147: misc.o: expand.h
                   18148: misc.o: misc.c
                   18149: misc.o: sh.h
                   18150: misc.o: stdh.h
                   18151: misc.o: trace.h
                   18152: strstr.o: stdh.h
                   18153: strstr.o: strstr.c
                   18154: syn.o: config.h
                   18155: syn.o: expand.h
                   18156: syn.o: lex.h
                   18157: syn.o: sh.h
                   18158: syn.o: stdh.h
                   18159: syn.o: syn.c
                   18160: syn.o: table.h
                   18161: syn.o: trace.h
                   18162: syn.o: tree.h
                   18163: sigact.o: sigact.h sigact.c
                   18164: table.o: config.h
                   18165: table.o: sh.h
                   18166: table.o: stdh.h
                   18167: table.o: table.c
                   18168: table.o: table.h
                   18169: table.o: trace.h
                   18170: times.o: times.c
                   18171: trace.o: trace.c
                   18172: trap.o: config.h
                   18173: trap.o: sh.h
                   18174: trap.o: stdh.h
                   18175: trap.o: trace.h
                   18176: trap.o: trap.c
                   18177: tree.o: config.h
                   18178: tree.o: sh.h
                   18179: tree.o: stdh.h
                   18180: tree.o: trace.h
                   18181: tree.o: tree.c
                   18182: tree.o: tree.h
                   18183: do_ulimit.o: config.h
                   18184: do_ulimit.o: sh.h
                   18185: do_ulimit.o: stdh.h
                   18186: do_ulimit.o: trace.h
                   18187: do_ulimit.o: do_ulimit.c
                   18188: var.o: config.h
                   18189: var.o: expand.h
                   18190: var.o: sh.h
                   18191: var.o: stdh.h
                   18192: var.o: table.h
                   18193: var.o: trace.h
                   18194: var.o: var.c
                   18195: version.o: config.h
                   18196: version.o: sh.h
                   18197: version.o: stdh.h
                   18198: version.o: trace.h
                   18199: version.o: version.c
                   18200: vi.o: config.h
                   18201: vi.o: edit.h
                   18202: vi.o: expand.h
                   18203: vi.o: lex.h
                   18204: vi.o: sh.h
                   18205: vi.o: stdh.h
                   18206: vi.o: table.h
                   18207: vi.o: trace.h
                   18208: vi.o: tree.h
                   18209: vi.o: vi.c
                   18210: # WARNING: Put nothing here or make depend will gobble it up!
                   18211: ./pdksh/std/  2755    653   1762           0  5302550313  10131 5ustar  hlu./pdksh/std/posix/  2755    653   1762           0  5302550303  11272 5ustar  hlu./pdksh/std/posix/io.h   644    653   1762        3017  5243743535  12130 0ustar  hlu/* POSIX IO functions */
                   18212: /* $Id: io.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18213: 
                   18214: /*
                   18215:  * the incomplete type "struct stat"
                   18216:  * will get warnings from GCC,
                   18217:  * errors from Turbo C. Too bad.
                   18218:  */
                   18219: 
                   18220: /* include <unistd.h> to get this */
                   18221: 
                   18222: #if ! _IO_H
                   18223: #define        _IO_H   1
                   18224: 
                   18225: #include <unistd.h>
                   18226: 
                   18227: #if _ST                                /* dLibs hack */
                   18228: #define        unlink  remove
                   18229: #endif
                   18230: 
                   18231: struct stat;                   /* create global incompletely-typed structure */
                   18232: 
                   18233: int chdir ARGS ((const char *path));
                   18234: #ifndef sparc
                   18235: int umask ARGS ((int mode));
                   18236: #endif
                   18237: 
                   18238: int open ARGS ((const char *path, int flags, ... /*mode*/));
                   18239: int creat ARGS ((const char *path, int mode));
                   18240: int pipe ARGS ((int pv[2]));
                   18241: int close ARGS ((int fd));
                   18242: 
                   18243: int fcntl ARGS ((int fd, int cmd, int arg));
                   18244: int dup ARGS ((int fd));
                   18245: int dup2 ARGS ((int ofd, int nfd));
                   18246: 
                   18247: int link ARGS ((const char *opath, const char *npath));
                   18248: int unlink ARGS ((const char *path));
                   18249: int rename ARGS ((const char *opath, const char *npath));
                   18250: int mkdir ARGS ((const char *path, int mode));
                   18251: 
                   18252: long lseek ARGS ((int fd, long off, int how));
                   18253: int read ARGS ((int fd, char *buf, unsigned len));
                   18254: int write ARGS ((int fd, char *buf, unsigned len));
                   18255: 
                   18256: int access ARGS ((const char *path, int mode));
                   18257: int stat ARGS ((const char *path, struct stat *sp));
                   18258: int fstat ARGS ((int fd, struct stat *sp));
                   18259: 
                   18260: int chmod ARGS ((const char *path, int mode));
                   18261: int chown ARGS ((const char *path, int uid));
                   18262: int chgrp ARGS ((const char *path, int gid));
                   18263: int utime ARGS ((const char *path, long tv[2]));
                   18264: 
                   18265: #if _BSD || _V7
                   18266: int ioctl ARGS ((int fd, int cmd, void *argp)); /* BSD is "uns long cmd" */
                   18267: #endif
                   18268: 
                   18269: #endif
                   18270: ./pdksh/std/posix/Makefile   644    653   1762        1760  5243743532  13010 0ustar  hlu# POSIX P1003.1 compatability
                   18271: # $Id: Makefile,v 1.2 1992/04/25 08:22:14 sjg Exp $
                   18272: 
                   18273: SHELL = /bin/sh
                   18274: MAKE  = make
                   18275: 
                   18276: #CONFIG = -D_SYSV
                   18277: CONFIG = -D_BSD
                   18278: 
                   18279: LN = ln
                   18280: RANLIB = ranlib                # For BSD systems
                   18281: #RANLIB = echo Updated
                   18282: 
                   18283: LIB = ../libposix.a
                   18284: INCL = ../h
                   18285: 
                   18286: CFLAGS = $(CCOPTS) -I$(INCL) $(CONFIG)
                   18287: 
                   18288: MISC = Makefile 
                   18289: HDRS = io.h unistd.h fcntl.h dirent.h 
                   18290: SYSHDRS = wait.h time.h times.h
                   18291: 
                   18292: SRCS = unistd.c fcntl.c times.c dup2.c
                   18293: OBJS = $(LIB)(unistd.o) \
                   18294:        $(LIB)(fcntl.o) \
                   18295:        $(LIB)(times.o) \
                   18296:        $(LIB)(dup2.o)
                   18297: 
                   18298: all:   $(LIB)
                   18299: 
                   18300: link:  $(HDRS)
                   18301:        [ -d $(INCL) ] || mkdir $(INCL)
                   18302:        [ -d $(INCL)/sys ] || mkdir $(INCL)/sys
                   18303:        ($(SHELL) ../mklinks $(INCL) $(HDRS))
                   18304:        ($(SHELL) ../mklinks $(INCL)/sys $(SYSHDRS))
                   18305:        -if [ -r /usr/include/unistd.h ]; then $(RM) $(INCL)/unistd.h; fi 
                   18306: 
                   18307: $(LIB):        $(OBJS)
                   18308: # if you make doesn't know how to put objects in libraries
                   18309: # then simply make all the .o's and use the following line
                   18310: #      ar r $@ $?
                   18311:        $(RANLIB) $@
                   18312: 
                   18313: clean:
                   18314:        -rm -f *.o *.out
                   18315: 
                   18316: clobber: clean
                   18317:        -rm -f $(LIB)
                   18318: 
                   18319: fcntl.o: fcntl.h 
                   18320: 
                   18321: times.o: times.h 
                   18322: ./pdksh/std/posix/dirent.C   644    653   1762        2105  5243743532  12733 0ustar  hlu/*
                   18323:  * simple implementation of directory(3) routines for V7 and Minix.
                   18324:  * completly untested. not designed to be efficient.
                   18325:  * missing telldir and seekdir.
                   18326:  */
                   18327: /* $Id: dirent.C,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18328: 
                   18329: #include <sys/types.h>
                   18330: #include <dirent.h>
                   18331: 
                   18332: char   *malloc();
                   18333: 
                   18334: #define        DIRSIZ  14
                   18335: struct direct_v7
                   18336: {
                   18337:        unsigned short  d_ino;
                   18338:        char    d_name[DIRSIZ];
                   18339: };
                   18340: 
                   18341: DIR *opendir(filename)
                   18342:        char *filename;
                   18343: {
                   18344:        DIR *dirp;
                   18345: 
                   18346:        dirp = (DIR *) malloc(sizeof(DIR));
                   18347:        if (dirp == NULL)
                   18348:                return NULL;
                   18349:        dirp->fd = open(filename, 0);
                   18350:        if (dirp->fd < 0) {
                   18351:                free((char *) dirp);
                   18352:                return NULL;
                   18353:        }
                   18354:        return dirp;
                   18355: }
                   18356: 
                   18357: struct dirent *readdir(dirp)
                   18358:        register DIR *dirp;
                   18359: {
                   18360:        static  struct direct_v7 ent;
                   18361: 
                   18362:        while (read(dirp->fd, (char *)&ent, (int)sizeof(ent)) == sizeof(ent))
                   18363:                if (ent.d_ino != 0)
                   18364:                        goto found;
                   18365:        return (struct dirent *) NULL;
                   18366:  found:
                   18367:        dirp->ent.d_ino = ent.d_ino;
                   18368:        strncpy(dirp->ent.d_name, ent.d_name, DIRSIZ);
                   18369:        return &dirp->ent;
                   18370: }
                   18371: 
                   18372: void rewinddir(dirp)
                   18373:        DIR *dirp;
                   18374: {
                   18375:        lseek(dirp->fd, 0L, 0);
                   18376: }
                   18377: 
                   18378: closedir(dirp)
                   18379:        DIR *dirp;
                   18380: {
                   18381:        close(dirp->fd);
                   18382:        dirp->fd = -1;
                   18383:        free((char *) dirp);
                   18384:        return 0;
                   18385: }
                   18386: ./pdksh/std/posix/dirent.H   644    653   1762        1650  5243743533  12745 0ustar  hlu/*
                   18387:        <sys/dirent.h> -- file system independent directory entry (SVR3)
                   18388: 
                   18389:        last edit:      25-Apr-1987     D A Gwyn
                   18390:        last hack:      14-Aug-1987     Eric Gisin
                   18391: 
                   18392:        prerequisite:   <sys/types.h>
                   18393: */
                   18394: /* $Id: dirent.H,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18395: 
                   18396: #define        MAXNAMLEN       16              /* maximum filename length */
                   18397: 
                   18398: struct dirent                          /* data from getdents()/readdir() */
                   18399:        {
                   18400:        long            d_ino;          /* inode number of entry */
                   18401:        off_t           d_off;          /* offset of disk directory entry */
                   18402:        unsigned short  d_reclen;       /* length of this record */
                   18403:        char    d_name[MAXNAMLEN];      /* name of file */
                   18404: };
                   18405: 
                   18406: #ifndef NAME_MAX
                   18407: #define        NAME_MAX        (MAXNAMLEN - 1) /* DAG -- added for POSIX */
                   18408: #endif
                   18409: 
                   18410: typedef struct {                       /* returned by opendir() */
                   18411:        int     fd;
                   18412:        struct dirent ent;
                   18413: } DIR;
                   18414: 
                   18415: extern DIR             *opendir();
                   18416: extern struct dirent   *readdir();
                   18417: extern off_t           telldir();
                   18418: extern void            seekdir();
                   18419: extern void            rewinddir();
                   18420: extern int             closedir();
                   18421: 
                   18422: #ifndef NULL
                   18423: #define        NULL    0                       /* DAG -- added for convenience */
                   18424: #endif
                   18425: ./pdksh/std/posix/fcntl.c   644    653   1762         745  5243743534  12606 0ustar  hlu/* fcntl emulation */
                   18426: /* $Id: fcntl.c,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18427: 
                   18428: #include <errno.h>
                   18429: #include <sys/types.h>
                   18430: #include <unistd.h>
                   18431: #include <fcntl.h>
                   18432: 
                   18433: #if _V7
                   18434: 
                   18435: #include <sgtty.h>
                   18436: 
                   18437: int
                   18438: fcntl(fd, cmd, arg)
                   18439:        int fd, cmd, arg;
                   18440: {
                   18441:        switch (cmd) {
                   18442:          case F_SETFD:         /* set fd flags */
                   18443:                ioctl(fd, (arg&FD_CLEXEC) ? FIOCLEX : FIONCLEX, (char *)NULL);
                   18444:                break;
                   18445:          case F_DUPFD:         /* dup fd */
                   18446:                /* this one is fun. find an unused fd >= arg and dup2 */
                   18447:                break;
                   18448:        }
                   18449:        return 0;
                   18450: }
                   18451: 
                   18452: #endif
                   18453: 
                   18454: ./pdksh/std/posix/fcntl.h   644    653   1762         753  5243743534  12612 0ustar  hlu/* P1003.1 fcntl/open definitions */
                   18455: /* Based on a version by Terrence W. Holm */
                   18456: /*  for fcntl(2)  */
                   18457: /* $Id: fcntl.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18458: 
                   18459: #define        F_DUPFD         0
                   18460: #define        F_GETFD         1
                   18461: #define        F_SETFD         2
                   18462: #define        F_GETFL         3
                   18463: #define        F_SETFL         4
                   18464: 
                   18465: #define        FD_CLEXEC       1               /* fcntl F_SETFD close on exec mode */
                   18466: 
                   18467: /*  for open(2)  */
                   18468: 
                   18469: #define        O_RDONLY        0
                   18470: #define        O_WRONLY        1
                   18471: #define        O_RDWR          2
                   18472: 
                   18473: #if _BSD
                   18474: #undef O_RDONLY
                   18475: #undef O_WRONLY
                   18476: #undef O_RDWR
                   18477: #include "/./usr/include/fcntl.h"
                   18478: #endif
                   18479: 
                   18480: ./pdksh/std/posix/fixincludes   644    653   1762        1437  5243742777  13623 0ustar  hlu# Install modified versions of certain ANSI-incompatible system header files
                   18481: # which are fixed to work correctly with ANSI C
                   18482: # and placed in a directory that GNU C will search.
                   18483: # This works properly on a Sun in system version 3.4;
                   18484: # for other versions, you had better check.
                   18485: 
                   18486: mkdir /usr/local/lib/gcc-include
                   18487: mkdir /usr/local/lib/gcc-include/sys
                   18488: cp /usr/include/sys/ioctl.h /usr/local/lib/gcc-include/sys/ioctl.h
                   18489: chmod +w /usr/local/lib/gcc-include/sys/ioctl.h
                   18490: ex /usr/local/lib/gcc-include/sys/ioctl.h <<\EOF
                   18491: g/_IO/s/(\(.\),/('\1',/
                   18492: g/#define._IO/s/'x'/x/g
                   18493: wq
                   18494: EOF
                   18495: 
                   18496: cp /usr/include/sys/ttychars.h /usr/local/lib/gcc-include/sys/ttychars.h
                   18497: chmod +w /usr/local/lib/gcc-include/sys/ttychars.h
                   18498: ex /usr/local/lib/gcc-include/sys/ttychars.h <<\EOF
                   18499: g/CTRL/s/(\(.\))/('\1')/
                   18500: g/#define.CTRL/s/'c'/c/g
                   18501: wq
                   18502: EOF
                   18503: ./pdksh/std/posix/times.c   644    653   1762        2235  5243743536  12637 0ustar  hlu/* P1003.1 times emulation */
                   18504: /* $Id: times.c,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18505: 
                   18506: #include <sys/times.h>
                   18507: 
                   18508: #if _BSD
                   18509: 
                   18510: #include <sys/time.h>
                   18511: #include <sys/resource.h>
                   18512: 
                   18513: static long base_tv_sec = 0;
                   18514: 
                   18515: clock_t
                   18516: times(tmsp)
                   18517:        register struct tms *tmsp;
                   18518: {
                   18519:        struct timeval tv;
                   18520:        struct rusage ru;
                   18521: 
                   18522:        getrusage(RUSAGE_SELF, &ru);
                   18523:        tmsp->tms_utime = ru.ru_utime.tv_sec*CLK_TCK
                   18524:                + (long)ru.ru_utime.tv_usec*CLK_TCK/1000000;
                   18525:        tmsp->tms_stime = ru.ru_stime.tv_sec*CLK_TCK
                   18526:                + (long)ru.ru_stime.tv_usec*CLK_TCK/1000000;
                   18527:        getrusage(RUSAGE_CHILDREN, &ru);
                   18528:        tmsp->tms_cutime = ru.ru_utime.tv_sec*CLK_TCK
                   18529:                + (long)ru.ru_utime.tv_usec*CLK_TCK/1000000;
                   18530:        tmsp->tms_cstime = ru.ru_stime.tv_sec*CLK_TCK
                   18531:                + (long)ru.ru_stime.tv_usec*CLK_TCK/1000000;
                   18532: 
                   18533:        gettimeofday(&tv, (struct timezone *)NULL);
                   18534:        if (base_tv_sec == 0)
                   18535:                base_tv_sec = tv.tv_sec;
                   18536:        tv.tv_sec -= base_tv_sec; /*  prevent clock_t overflow */
                   18537:        return tv.tv_sec*CLK_TCK + (long)tv.tv_usec*CLK_TCK/1000000;
                   18538: }
                   18539: 
                   18540: #endif
                   18541: 
                   18542: #if _V7
                   18543: 
                   18544: clock_t
                   18545: times(tmsp)
                   18546:        struct tms *tmsp;
                   18547: {
                   18548:        struct timeb tb;
                   18549: 
                   18550: #undef times                   /* access real times() */
                   18551:        times(tmsp);
                   18552: #define times times_
                   18553:        ftime(&tb);
                   18554:        return tb.time*CLK_TCK + (long)tb.millitm*CLK_TCK/1000;
                   18555: }
                   18556: 
                   18557: #endif
                   18558: 
                   18559: ./pdksh/std/posix/times.h   644    653   1762         632  5243743536  12623 0ustar  hlu/*
                   18560:  * sys/times.h: POSIX times()
                   18561:  */
                   18562: /* $Id: times.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18563: 
                   18564: #if ! _TIMES_H
                   18565: #define        _TIMES_H 1
                   18566: 
                   18567: #include <time.h>              /* defines CLK_TCK */
                   18568: 
                   18569: #if __STDC__
                   18570: #define        ARGS(args)      args
                   18571: #else
                   18572: #define        ARGS(args)      ()
                   18573: #endif
                   18574: 
                   18575: struct tms {
                   18576:        clock_t tms_utime, tms_stime;
                   18577:        clock_t tms_cutime, tms_cstime;
                   18578: };
                   18579: 
                   18580: #if _V7
                   18581: #define times times_
                   18582: #endif
                   18583: 
                   18584: clock_t        times ARGS((struct tms *tmsp));
                   18585: 
                   18586: #endif
                   18587: 
                   18588: ./pdksh/std/posix/unistd.c   644    653   1762        1032  5243743537  13017 0ustar  hlu/* misc. POSIX emulation */
                   18589: 
                   18590: #ifndef lint
                   18591: static char *RCSid = "$Id: unistd.c,v 1.2 1992/04/25 08:22:14 sjg Exp $";
                   18592: #endif
                   18593: 
                   18594: #include <string.h>
                   18595: #include <errno.h>
                   18596: #include <sys/types.h>
                   18597: #include <unistd.h>
                   18598: 
                   18599: #if _V7 || _BSD
                   18600: 
                   18601: char *
                   18602: getcwd(buf, len)
                   18603:        char *buf;
                   18604:        size_t len;
                   18605: {
                   18606:        char cwd [1024];
                   18607:        extern char *getwd();
                   18608:        if (getwd(cwd) == NULL)
                   18609:                return NULL;
                   18610:        if (strlen(cwd)+1 >= len) {
                   18611:                errno = ERANGE;
                   18612:                return NULL;
                   18613:        }
                   18614:        return strcpy(buf, cwd);
                   18615: }
                   18616: 
                   18617: #endif
                   18618: 
                   18619: #if _V7
                   18620: 
                   18621: long
                   18622: ulimit(cmd, limit)
                   18623:        int cmd;
                   18624:        long limit;
                   18625: {
                   18626:        return 0;
                   18627: }
                   18628: 
                   18629: #endif
                   18630: 
                   18631: ./pdksh/std/posix/unistd.h   644    653   1762        1506  5243743537  13032 0ustar  hlu/* unistd.h: misc. P1003.1 definitions */
                   18632: /* Based on a version by Terrence W. Holm */
                   18633: /* $Id: unistd.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18634: 
                   18635: #if ! _UNISTD_H
                   18636: #define        _UNISTD_H 1
                   18637: 
                   18638: #include <stddef.h>
                   18639: 
                   18640: /* doesn't really belong here, but the library function need it */
                   18641: /* todo: use _ARGS, _void, _const */
                   18642: #if __STDC__
                   18643: #define        ARGS(args)      args
                   18644: #define void   void
                   18645: #define        const   const
                   18646: #else
                   18647: #define        ARGS(args)      ()
                   18648: #define        void    char
                   18649: #define        const
                   18650: #endif
                   18651: 
                   18652: #include <io.h>                        /* POSIX IO functions */
                   18653: 
                   18654: /*  for access(2)  */
                   18655: 
                   18656: #define        R_OK    4
                   18657: #define        W_OK    2
                   18658: #define        X_OK    1
                   18659: #define        F_OK    0
                   18660: 
                   18661: /*  for lockf(2)  */
                   18662: 
                   18663: #define        F_ULOCK 0
                   18664: #define        F_LOCK  1
                   18665: #define        F_TLOCK 2
                   18666: #define        F_TEST  3
                   18667: 
                   18668: /*  for lseek(2)  */
                   18669: 
                   18670: #define        SEEK_SET        0
                   18671: #define        SEEK_CUR        1
                   18672: #define        SEEK_END        2
                   18673: 
                   18674: #define        IN_PATH "/usr/include"
                   18675: 
                   18676: char   *getcwd ARGS ((char *buf, size_t len));
                   18677: 
                   18678: #endif
                   18679: 
                   18680: ./pdksh/std/posix/wait.h   644    653   1762        2231  5243743540  12456 0ustar  hlu/*
                   18681:  * POSIX <sys/wait.h>
                   18682:  */
                   18683: /* $Id: wait.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18684: #if __STDC__
                   18685: #define        ARGS(args)      args
                   18686: #else
                   18687: #define        ARGS(args)      ()
                   18688: #endif
                   18689: 
                   18690: #ifdef HAVE_SYS_STDTYPES
                   18691: # include <sys/stdtypes.h>
                   18692: #else
                   18693: # ifndef _PID_T
                   18694: #   define _PID_T
                   18695: typedef int pid_t;             /* belong in sys/types.h */
                   18696: # endif
                   18697: #endif
                   18698: 
                   18699: #ifdef sun
                   18700: # include "/./usr/include/sys/wait.h"
                   18701: #else
                   18702: 
                   18703: #define WAIT_T int
                   18704: 
                   18705: /* waitpid options */
                   18706: #define WNOHANG                1       /* don't hang in wait */
                   18707: #define WUNTRACED      2       /* tell about stopped, untraced children */
                   18708: 
                   18709: #define        WSTOPPED        0x7F    /* process is stopped */
                   18710: 
                   18711: #define WIFSTOPPED(x)  (((x)&0xFF) == 0x7F)
                   18712: #define WIFSIGNALED(x) (((x)&0xFF) != 0x7F && ((x)&0x7F) != 0)
                   18713: #define WIFEXITED(x)   (((x)&0xFF) != 0x7F && ((x)&0x7F) == 0)
                   18714: #define        WIFCORED(x)     (!!((x)&0x80)) /* non-standard */
                   18715: #define        WEXITSTATUS(x)  ((x)>>8&0xFF)
                   18716: #define        WTERMSIG(x)     ((x)&0x7F)
                   18717: #define        WSTOPSIG(x)     ((x)>>8&0xFF)
                   18718: 
                   18719: pid_t wait ARGS((int *statp));
                   18720: #if _BSD
                   18721: pid_t wait3 ARGS((int *statp, int options, void *));
                   18722: /* todo: does not emulate pid argument */
                   18723: #define        waitpid(pid, sp, opts)  wait3(sp, opts, (void*)NULL)
                   18724: #else
                   18725: pid_t waitpid ARGS((pid_t pid, int *statp, int options));
                   18726: #endif
                   18727: 
                   18728: #endif /* sparc */
                   18729: ./pdksh/std/posix/dirent.h   644    653   1762         127  5243743024  12756 0ustar  hlu/* <dirent.h> based on BSD <sys/dir.h> */
                   18730: 
                   18731: #include <sys/dir.h>
                   18732: #define dirent direct
                   18733: 
                   18734: ./pdksh/std/posix/dup2.c   644    653   1762         514  5243743533  12343 0ustar  hlu/*
                   18735:  * Cheap imitation of BSD dup2()
                   18736:  */
                   18737: /* $Id: dup2.c,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18738: 
                   18739: #include <fcntl.h>
                   18740: 
                   18741: #if _SYSV
                   18742: int
                   18743: dup2( oldd, newd )
                   18744: int    oldd, newd;
                   18745: {
                   18746:        int     fd;
                   18747: 
                   18748:        if (fcntl( oldd, F_GETFL, 0 ) < 0)
                   18749:                return( -1 );
                   18750: 
                   18751:        (void) close( newd );
                   18752:        fd = fcntl( oldd, F_DUPFD, newd );
                   18753: 
                   18754:        return( (fd > newd) ? -1 : fd );
                   18755: }
                   18756: #endif
                   18757: ./pdksh/std/posix/time.h   644    653   1762         510  5243743536  12433 0ustar  hlu/*
                   18758:  * Replacement for BSD <sys/time.h>
                   18759:  * because Ultrix screws it up.
                   18760:  */
                   18761: /* $Id: time.h,v 1.2 1992/04/25 08:22:14 sjg Exp $ */
                   18762: 
                   18763: struct timeval {
                   18764:        long tv_sec;            /* time_t */
                   18765:        long tv_usec;           /* microsex */
                   18766: };
                   18767: 
                   18768: struct timezone {
                   18769:        int tz_minuteswest;     /* of Greenwinch */
                   18770:        int tz_dsttime;         /* type of dst correction to apply */
                   18771: };
                   18772: ./pdksh/std/posix/ChangeLog   644    653   1762         305  5243743531  13073 0ustar  hluSat Apr 25 14:51:33 1992  Simon J. Gerraty  (sjg@zen)
                   18773: 
                   18774:        * Added RCS keys to sources.
                   18775: 
                   18776: Mon Nov 25 13:17:04 1991  Simon J. Gerraty  (sjg at zen)
                   18777: 
                   18778:        * wait.h: use "/./usr/include/sys/wait.h for sun's
                   18779: 
                   18780: ./pdksh/std/stdc/  2755    653   1762           0  5302550312  11065 5ustar  hlu./pdksh/std/stdc/stdio.c   644    653   1762         616  5243743550  12410 0ustar  hlu/*
                   18781:  * Emulation of misc. ANSI C stdio functions
                   18782:  */
                   18783: 
                   18784: /* $Id: stdio.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   18785: 
                   18786: #include <stdio.h>
                   18787: 
                   18788: #ifndef __STDC__
                   18789: #define const
                   18790: #define volatile
                   18791: #endif
                   18792: 
                   18793: #if 1
                   18794: int
                   18795: remove(name)
                   18796:        const char *name;
                   18797: {
                   18798:        return unlink(name);
                   18799: }
                   18800: #endif
                   18801: 
                   18802: #if _V7
                   18803: int
                   18804: rename(oname, nname)
                   18805:        const char *oname, *nname;
                   18806: {
                   18807:        return link(oname, nname) == 0 && unlink(oname) == 0 ? 0 : -1;
                   18808: }
                   18809: #endif
                   18810: 
                   18811: ./pdksh/std/stdc/vprintf.c   644    653   1762       12004  5243743642  13012 0ustar  hlu#ifndef lint
                   18812: static char *RCSid = "$Id: vprintf.c,v 1.3 1992/05/12 09:31:03 sjg Exp $";
                   18813: #endif
                   18814: #ifdef __STDC__
                   18815: #include <stdarg.h>
                   18816: #else
                   18817: #include <varargs.h>
                   18818: #endif
                   18819: #include <stdio.h>
                   18820: 
                   18821: #define        BUF     40              /* buffer for int -> string conversion */
                   18822: 
                   18823: int
                   18824: #ifdef __STDC__
                   18825: vprintf(const char *fmt, va_list va) {
                   18826: #else
                   18827: vprintf(fmt, va) char *fmt; va_list va; {
                   18828: #endif
                   18829:        return vfprintf(stdout, fmt, va);
                   18830: }
                   18831: 
                   18832: int
                   18833: #ifdef __STDC__
                   18834: vfprintf(register FILE *f, register const char *fmt, register va_list va) {
                   18835: #else
                   18836: vfprintf(f, fmt, va) register FILE *f; register char *fmt; register va_list va; {
                   18837: #endif
                   18838:        register int c;
                   18839:        int pos = 0;                    /* todo: implement */
                   18840: 
                   18841:        while ((c = *fmt++))
                   18842:            if (c == '%') {
                   18843:                long n;
                   18844:                register unsigned long u;
                   18845:                char buf [BUF+1];
                   18846:                register char *p = buf + BUF;
                   18847:                register enum {
                   18848:                        FF_ALT = 0x01, /* #, alternate format */
                   18849:                        FF_SHORT = 0x02, /* h, short arg */
                   18850:                        FF_LONG = 0x04, /* l, long arg */
                   18851:                        FF_ZERO = 0x08, /* 0, zero fill */
                   18852:                        FF_LEFT = 0x10, /* -, left adjust */
                   18853:                        FF_PREC = 0x20, /* .*, precision */
                   18854:                        FF_NEG = 0x40,  /* signed arg */
                   18855:                        FF_PUTS = 0x80, /* fputs(p, f) */
                   18856:                        FF_DEFAULT = 0
                   18857:                } flags = FF_DEFAULT;
                   18858:                int sign = '-'; /* sign: [ +-] */
                   18859:                int width = 0, prec = 0; /* width, precision */
                   18860: 
                   18861:                *p = 0;
                   18862: 
                   18863:                /* scan flag characters */
                   18864:                for (c = *fmt++; ; c = *fmt++) switch (c) {
                   18865:                  case '0':
                   18866:                        flags |= FF_ZERO;
                   18867:                        break;
                   18868: 
                   18869:                  case '#':             /* alternate format */
                   18870:                        flags |= FF_ALT;
                   18871:                        break;
                   18872: 
                   18873:                  case ' ':             /* blank sign */
                   18874:                        sign = ' ';
                   18875:                        break;
                   18876:                  case '+':             /* +/- sign */
                   18877:                        sign = '+';
                   18878:                        break;
                   18879: 
                   18880:                  case '-':             /* left just. */
                   18881:                        flags |= FF_LEFT;
                   18882:                        break;
                   18883: 
                   18884:                  default:
                   18885:                        goto Frogs;
                   18886:                }
                   18887:          Frogs:
                   18888: 
                   18889:                /* scan width */
                   18890:                if (c == '*') {         /* width from arg list */
                   18891:                        width = va_arg(va, int);
                   18892:                        c = *fmt++;
                   18893:                } else
                   18894:                        while ('0' <= c && c <= '9') {
                   18895:                                width = width*10 + (c-'0');
                   18896:                                c = *fmt++;
                   18897:                        }
                   18898: 
                   18899:                if (c == '.') {         /* scan precision */
                   18900:                        flags |= FF_PREC;
                   18901:                        c = *fmt++;
                   18902:                        if (c == '*') { /* precision from arg list */
                   18903:                                prec = va_arg(va, int);
                   18904:                                c = *fmt++;
                   18905:                        } else
                   18906:                                while ('0' <= c && c <= '9') {
                   18907:                                        prec = prec*10 + (c-'0');
                   18908:                                        c = *fmt++;
                   18909:                                }
                   18910:                }
                   18911: 
                   18912:                /* length modifiers */
                   18913:                if (c == 'h') {
                   18914:                        flags |= FF_SHORT;
                   18915:                        c = *fmt++;
                   18916:                } else if (c == 'l') {
                   18917:                        flags |= FF_LONG;
                   18918:                        c = *fmt++;
                   18919:                }
                   18920: 
                   18921:                /* do conversion */
                   18922:                switch (c) {
                   18923:                  case '%':             /* %% -> % */
                   18924:                        putc(c, f);
                   18925:                        pos ++;
                   18926:                        break;
                   18927: 
                   18928:                  case 'p':             /* pointer */
                   18929:                        *--p = '}';
                   18930:                        u = (unsigned long) va_arg(va, void*);
                   18931:                        do {
                   18932:                                *--p = "0123456789ABCDEF"[u%16];
                   18933:                                u /= 16;
                   18934:                        } while (u != 0);
                   18935:                        *--p = '{';
                   18936:                        flags |= FF_PUTS;
                   18937:                        break;
                   18938: 
                   18939:                  case 'n':             /* save position */
                   18940:                        *va_arg(va, int*) = pos;
                   18941:                        break;
                   18942: 
                   18943:                  case 'c':             /* character */
                   18944:                        u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
                   18945:                          : (flags&&FF_LONG) ? va_arg(va, unsigned long)
                   18946:                          : va_arg(va, unsigned int);
                   18947:                        *--p = u;
                   18948:                        flags |= FF_PUTS;
                   18949:                        break;
                   18950: 
                   18951:                  case 's':             /* string */
                   18952:                        if ((p = va_arg(va, char *)) == NULL)
                   18953:                          p = "";
                   18954:                        if ((flags&FF_PREC) && strlen(p) > prec) {
                   18955:                                pos += prec;
                   18956:                                while (--prec >= 0)
                   18957:                                {
                   18958:                                  c = *p++;
                   18959:                                  putc(c, f);
                   18960:                                }
                   18961:                                break;
                   18962:                        }
                   18963:                        flags |= FF_PUTS;
                   18964:                        break;
                   18965: 
                   18966:                  case 'i': case 'd': case 'u': /* decimal */
                   18967:                        if (c != 'u') { /* signed */
                   18968:                                n = (flags&FF_SHORT) ? va_arg(va, short)
                   18969:                                  : (flags&&FF_LONG) ? va_arg(va, long)
                   18970:                                  : va_arg(va, int);
                   18971:                                if (n < 0)
                   18972:                                        flags |= FF_NEG;
                   18973:                                u = (n < 0) ? -n : n;
                   18974:                        } else
                   18975:                                u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
                   18976:                                  : (flags&&FF_LONG) ? va_arg(va, unsigned long)
                   18977:                                  : va_arg(va, unsigned int);
                   18978:                        do {
                   18979:                                *--p = '0' + u%10;
                   18980:                                u /= 10;
                   18981:                        } while (u != 0);
                   18982:                        prec -= buf+BUF - p;
                   18983:                        while (--prec >= 0)
                   18984:                                *--p = '0';
                   18985:                        if (flags&FF_NEG)
                   18986:                                *--p = '-';
                   18987:                        else
                   18988:                                if (sign != '-')
                   18989:                                        *--p = (sign == '+') ? '+' : ' ';
                   18990:                        flags |= FF_PUTS;
                   18991:                        break;
                   18992: 
                   18993:                  case 'x': case 'X':   /* hex, Hex */
                   18994:                        u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
                   18995:                          : (flags&&FF_LONG) ? va_arg(va, unsigned long)
                   18996:                          : va_arg(va, unsigned int);
                   18997:                        do {
                   18998:                                *--p = "0123456789ABCDEF"[u%16];
                   18999:                                u /= 16;
                   19000:                        } while (u != 0);
                   19001:                        prec -= buf+BUF - p;
                   19002:                        while (--prec >= 0)
                   19003:                                *--p = '0';
                   19004:                        if (flags&&FF_ALT)
                   19005:                                *--p = 'x', *--p = '0';
                   19006:                        flags |= FF_PUTS;
                   19007:                        break;
                   19008: 
                   19009:                  case 'o':             /* octal */
                   19010:                        u = (flags&FF_SHORT) ? va_arg(va, unsigned short)
                   19011:                          : (flags&&FF_LONG) ? va_arg(va, unsigned long)
                   19012:                          : va_arg(va, unsigned int);
                   19013:                        do {
                   19014:                                *--p = '0' + u%8;
                   19015:                                u /= 8;
                   19016:                        } while (u != 0);
                   19017:                        prec -= buf+BUF - p;
                   19018:                        while (--prec >= 0)
                   19019:                                *--p = '0';
                   19020:                        if (flags&&FF_ALT && *p != '0')
                   19021:                                *--p = '0';
                   19022:                        flags |= FF_PUTS;
                   19023:                        break;
                   19024: 
                   19025:                  default:              /* todo: error */
                   19026:                        putc('%', f);
                   19027:                        putc(c, f);
                   19028:                        pos += 2;
                   19029:                        break;
                   19030:                }
                   19031: 
                   19032:                /* copy adjusted string "p" to output */
                   19033:                if (flags&FF_PUTS) {
                   19034:                        int len = strlen(p);
                   19035:                        int pad = width - len;
                   19036:                        if (!(flags&FF_LEFT))
                   19037:                                while (--pad >= 0)
                   19038:                                        putc((flags&FF_ZERO) ? '0' : ' ', f);
                   19039:                        while (c = *p++)
                   19040:                                putc(c, f);
                   19041:                        if ((flags&FF_LEFT))
                   19042:                                while (--pad >= 0)
                   19043:                                        putc(' ', f);
                   19044:                        pos += (len < width) ? width : len;
                   19045:                }
                   19046:            } else {                    /* ordinary character */
                   19047:                putc(c, f);
                   19048:                pos ++;
                   19049:            }
                   19050:        return pos;
                   19051: }
                   19052: 
                   19053: ./pdksh/std/stdc/stdio.h_std   644    653   1762        4356  5243743642  13316 0ustar  hlu/*
                   19054:  * ANSI stream IO
                   19055:  *
                   19056:  * Heavily dependent on /usr/include/stdio.h being AT&T derived.
                   19057:  * todo: needs L_* constants.
                   19058:  */
                   19059: 
                   19060: /* $Id: stdio.h_std,v 1.1 1992/05/02 13:29:18 sjg Exp $ */
                   19061: 
                   19062: #if ! _STDIO_H
                   19063: #define        _STDIO_H 1
                   19064: 
                   19065: #include <stddef.h>
                   19066: 
                   19067: /* system stdio.h goes here ... %%% */
                   19068: /* ... end system stdio.h */
                   19069: #line 15 "stdio.h"
                   19070: 
                   19071: #ifndef _IOFBF
                   19072: #define        _IOFBF  00000
                   19073: #endif
                   19074: #ifndef _IOLBF
                   19075: #define        _IOLBF  00000           /* same as _IOFBF */
                   19076: #endif
                   19077: 
                   19078: #define        SEEK_SET        0
                   19079: #define        SEEK_CUR        1
                   19080: #define        SEEK_END        2
                   19081: 
                   19082: #if _SYSV
                   19083: #define        _EXTERN extern
                   19084: #else
                   19085: #define        _EXTERN 
                   19086: #endif
                   19087: 
                   19088: _EXTERN        int     remove ARGS((const char *name));
                   19089: _EXTERN        int     rename ARGS((const char *oname, const char *nname));
                   19090: _EXTERN        FILE   *tmpfile ARGS((void));
                   19091: _EXTERN        char   *tmpnam ARGS((char *s));
                   19092: 
                   19093: _EXTERN        FILE   *fopen ARGS((const char *name, const char *mode));
                   19094: _EXTERN        FILE   *freopen ARGS((const char *name, const char *mode, FILE *f));
                   19095: _EXTERN        FILE   *fdopen ARGS((int fd, const char *mode));
                   19096: _EXTERN        int     fflush ARGS((FILE *f));
                   19097: _EXTERN        int     fclose ARGS((FILE *f));
                   19098: _EXTERN        void    setbuf ARGS((FILE *f, char *buf));
                   19099: _EXTERN        int     setvbuf ARGS((FILE *f, char *buf, int flags, size_t len));
                   19100: 
                   19101: _EXTERN        int     fseek ARGS((FILE *f, long off, int how));
                   19102: _EXTERN        long    ftell ARGS((FILE *f));
                   19103: _EXTERN        void    rewind ARGS((FILE *f));
                   19104: 
                   19105: _EXTERN        int     printf ARGS((const char *fmt, ...));
                   19106: _EXTERN        int     fprintf ARGS((FILE *f, const char *fmt, ...));
                   19107: _EXTERN        int     sprintf ARGS((char *s, const char *fmt, ...));
                   19108: /* we do not include <stdarg.h> to prevent <varargs.h> conflicts */
                   19109: _EXTERN        int     vprintf ARGS((const char *fmt, Void *va));
                   19110: _EXTERN        int     vfprintf ARGS((FILE *f, const char *fmt, Void *va));
                   19111: _EXTERN        int     vsprintf ARGS((char *s, const char *fmt, Void *va));
                   19112: _EXTERN        int     scanf ARGS((const char *fmt, ...));
                   19113: _EXTERN        int     fscanf ARGS((FILE *f, const char *fmt, ...));
                   19114: _EXTERN        int     sscanf ARGS((const char *s, const char *fmt, ...));
                   19115: 
                   19116: _EXTERN        size_t  fread ARGS((void *ptr, size_t size, size_t n, FILE *f));
                   19117: _EXTERN        size_t  frwrite ARGS((const void *ptr, size_t size, size_t n, FILE *f));
                   19118: _EXTERN        int     fgetc ARGS((FILE *f));
                   19119: _EXTERN        int     fputc ARGS((int c, FILE *f));
                   19120: _EXTERN        char   *fgets ARGS((char *s, int len, FILE *f));
                   19121: _EXTERN        int     fputs ARGS((const char *s, FILE *f));
                   19122: _EXTERN        char   *gets ARGS((char *s));
                   19123: _EXTERN        int     puts ARGS((const char *s));
                   19124: 
                   19125: #endif
                   19126: 
                   19127: ./pdksh/std/stdc/Makefile   644    653   1762        4401  5243743640  12576 0ustar  hlu# Standard C (ANSI) compatabilaty
                   19128: # $Id: Makefile,v 1.3 1992/05/03 08:30:08 sjg Exp $
                   19129: 
                   19130: # edit this makefile such that only the functions that
                   19131: # your systems doesn't have are provided.
                   19132: 
                   19133: SHELL = /bin/sh
                   19134: MAKE  = make
                   19135: 
                   19136: #CONFIG = -D_SYSV
                   19137: CONFIG = -D_BSD
                   19138: 
                   19139: LN = ln
                   19140: RANLIB = ranlib                # For BSD systems
                   19141: #RANLIB = echo Updated
                   19142: 
                   19143: LIB = ../libstdc.a
                   19144: INCL = ../h
                   19145: 
                   19146: CFLAGS = $(CCOPTS) -I$(INCL) $(CONFIG)
                   19147: 
                   19148: MISC = Makefile #stdio.h_std
                   19149: HDRS = limits.h stddef.h stdlib.h string.h time.h #stdarg.h 
                   19150: SYSHDRS = types.h
                   19151: 
                   19152: SRCS = strstr.c memmove.c stdio.c clock.c fprintf.c memchr.c \
                   19153:        memcmp.c memcpy.c memset.c setvbuf.c sprintf.c \
                   19154:        stdio.c strcat.c strchr.c strcmp.c strcpy.c strcspn.c \
                   19155:        strerror.c strlen.c strncat.c strncmp.c strncpy.c \
                   19156:        strpbrk.c strrchr.c strspn.c strtok.c vprintf.c
                   19157: 
                   19158: # only add to this list the modules that you _need_
                   19159: # some of these are untested!
                   19160: OBJS = $(LIB)(strstr.o) \
                   19161:        $(LIB)(memmove.o) \
                   19162:        $(LIB)(clock.o) \
                   19163: #      $(LIB)(vprintf.o) \
                   19164: #      $(LIB)(fprintf.o) \
                   19165: #      $(LIB)(sprintf.o) \
                   19166: #      $(LIB)(strtok.o) \
                   19167: #      $(LIB)(memchr.o) \
                   19168: #      $(LIB)(memcmp.o) \
                   19169: #      $(LIB)(memcpy.o) \
                   19170: #      $(LIB)(memset.o) \
                   19171: #      $(LIB)(setvbuf.o) \
                   19172: #      $(LIB)(strcat.o) \
                   19173: #      $(LIB)(strchr.o) \
                   19174: #      $(LIB)(strcmp.o) \
                   19175: #      $(LIB)(strcpy.o) \
                   19176: #      $(LIB)(strcspn.o) \
                   19177: #      $(LIB)(strerror.o) \
                   19178: #      $(LIB)(strlen.o) \
                   19179: #      $(LIB)(strncat.o) \
                   19180: #      $(LIB)(strncmp.o) \
                   19181: #      $(LIB)(strncpy.o) \
                   19182: #      $(LIB)(strpbrk.o) \
                   19183: #      $(LIB)(strrchr.o) \
                   19184: #      $(LIB)(strspn.o) \
                   19185: #      $(LIB)(stdio.o) 
                   19186: #
                   19187: 
                   19188: 
                   19189: 
                   19190: all:   $(LIB)
                   19191: 
                   19192: link:  $(HDRS) #stdio.h 
                   19193:        [ -d $(INCL) ] || mkdir $(INCL)
                   19194:        [ -d $(INCL)/sys ] || mkdir $(INCL)/sys
                   19195:        ($(SHELL) ../mklinks $(INCL) $(HDRS))
                   19196:        ($(SHELL) ../mklinks $(INCL)/sys $(SYSHDRS))
                   19197: #      ($(SHELL) ../mklinks $(INCL) stdio.h)
                   19198: 
                   19199: $(LIB):        $(OBJS)
                   19200: # if you make doesn't know how to put objects in libraries
                   19201: # then simply make all the .o's and use the following line
                   19202: #      ar r $@ $?
                   19203:        $(RANLIB) $@
                   19204: 
                   19205: stdio.h: stdio.h_std stdio.sed /usr/include/stdio.h 
                   19206:        sed -f stdio.sed </usr/include/stdio.h >stdio.hacked
                   19207:        sed <stdio.h_std >stdio.h -e '/%%%/ r stdio.hacked'
                   19208:        rm stdio.hacked
                   19209: 
                   19210: clean:
                   19211:        -rm -f *.o *.out stdio.hacked
                   19212: 
                   19213: clobber: clean
                   19214:        -rm -f $(LIB) stdio.h
                   19215: 
                   19216: string.h: stddef.h
                   19217: 
                   19218: stdlib.h: stddef.h
                   19219: 
                   19220: stdio.h: stddef.h 
                   19221: 
                   19222: time.h: stddef.h
                   19223: 
                   19224: stdio.o: stdio.h
                   19225: 
                   19226: setvbuf.o: stdlib.h stdio.h
                   19227: 
                   19228: fprintf.o: stdarg.h stdio.h
                   19229: 
                   19230: sprintf.o: stdarg.h stdio.h
                   19231: 
                   19232: vprintf.o: stdarg.h stdio.h
                   19233: 
                   19234: strstr.o: string.h 
                   19235: 
                   19236: ./pdksh/std/stdc/clock.c   644    653   1762        1337  5243743003  12373 0ustar  hlu/* clock() */
                   19237: 
                   19238: #include <time.h>
                   19239: 
                   19240: #if _BSD
                   19241: 
                   19242: #include <sys/time.h>
                   19243: #include <sys/resource.h>
                   19244: 
                   19245: clock_t
                   19246: clock()
                   19247: {
                   19248:        struct timeval tv;
                   19249:        struct rusage ru;
                   19250: 
                   19251:        getrusage(RUSAGE_SELF, &ru);
                   19252:        tv.tv_sec = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
                   19253:        tv.tv_usec = ru.ru_utime.tv_usec + ru.ru_stime.tv_usec;
                   19254:        return tv.tv_sec*CLK_TCK + (long)tv.tv_usec*CLK_TCK/1000000;
                   19255: }
                   19256: 
                   19257: #endif
                   19258: 
                   19259: #if _V7 || _SYSV
                   19260: 
                   19261: #include <sys/times.h>
                   19262: 
                   19263: clock_t
                   19264: clock()
                   19265: {
                   19266:        struct tms tms;
                   19267: 
                   19268:        (void) times(&tms);
                   19269:        return tms.tms_utime + tms.tms_stime;
                   19270: }
                   19271: 
                   19272: #endif
                   19273: 
                   19274: #if _ST
                   19275: 
                   19276: #include <osbind.h>
                   19277: 
                   19278: clock_t
                   19279: clock()
                   19280: {
                   19281:        long save;
                   19282:        clock_t c;
                   19283: 
                   19284:        /* access the ST's 200 HZ system clock in protected memory */
                   19285:        save = Super(0L);
                   19286:        c = *((long *)0x04BA);
                   19287:        (void)Super(save);
                   19288:        return c;
                   19289: }
                   19290: 
                   19291: #endif
                   19292: 
                   19293: ./pdksh/std/stdc/fprintf.c   644    653   1762        1426  5243743640  12756 0ustar  hlu/*
                   19294:  * printf and fprintf
                   19295:  */
                   19296: 
                   19297: /* $Id: fprintf.c,v 1.3 1992/05/12 09:30:58 sjg Exp $ */
                   19298: 
                   19299: #ifdef __STDC__
                   19300: #include <stdarg.h>
                   19301: #else
                   19302: #include <varargs.h>
                   19303: #endif
                   19304: #include <stdio.h>
                   19305: 
                   19306: #if _V7 || _BSD
                   19307: 
                   19308: /* printf to stdout */
                   19309: int
                   19310: #ifdef __STDC__
                   19311: printf(const char *fmt, ...) {
                   19312: #else
                   19313: printf(va_alist) va_dcl
                   19314: {
                   19315:        char *fmt;
                   19316: #endif
                   19317:        va_list va;
                   19318: 
                   19319: #ifdef __STDC__
                   19320:        va_start(va, fmt);
                   19321: #else
                   19322:        va_start(va);
                   19323:        fmt = va_arg(va, char *);
                   19324: #endif
                   19325:        vfprintf(stdout, fmt, va);
                   19326:        va_end(va);
                   19327:        return 0;
                   19328: }
                   19329: 
                   19330: int
                   19331: #ifdef __STDC__
                   19332: fprintf(FILE *f, const char *fmt, ...) {
                   19333: #else
                   19334: fprintf(va_alist) va_dcl
                   19335: {
                   19336:        FILE *f;
                   19337:        char *fmt;
                   19338: #endif
                   19339:        va_list va;
                   19340: 
                   19341: #ifdef __STDC__
                   19342:        va_start(va, fmt);
                   19343: #else
                   19344:        va_start(va);
                   19345:        f = va_arg(va, FILE *);
                   19346:        fmt = va_arg(va, char *);
                   19347: #endif
                   19348:        vfprintf(f, fmt, va);
                   19349:        va_end(va);
                   19350:        return 0;
                   19351: }
                   19352: 
                   19353: #endif
                   19354: ./pdksh/std/stdc/limits.h   644    653   1762        1727  5243743004  12612 0ustar  hlu/* Implementation-defined limits */
                   19355: 
                   19356: #if __STDC__
                   19357: #define        Signed  signed
                   19358: #else
                   19359: #define        Signed  
                   19360: #endif
                   19361: 
                   19362: #define        CHAR_BIT        8
                   19363: 
                   19364: #define        _S_MIN(type)    (-(Signed type)((unsigned type) ~0 >> 1) - 1)
                   19365: #define        _S_MAX(type)    ((Signed type)((unsigned type) ~0 >> 1))
                   19366: 
                   19367: #define        UCHAR_MIN       ((unsigned char) 0)
                   19368: #define        UCHAR_MAX       ((unsigned char) ~0)
                   19369: #define        SCHAR_MIN       _S_MIN(char)
                   19370: #define        SCHAR_MAX       _S_MAX(char)
                   19371: 
                   19372: /* some PCC compilers don't like the "elegant" definition of _UCHAR */
                   19373: /* let the poor user provide -D_UCHAR=0 or 1 */
                   19374: #ifndef _UCHAR
                   19375: #define        _UCHAR          ((char) ~0 == (unsigned char) ~0)
                   19376: #endif
                   19377: #define        CHAR_MIN        (_UCHAR ? UCHAR_MIN : SCHAR_MIN)
                   19378: #define        CHAR_MAX        (_UCHAR ? UCHAR_MAX : SCHAR_MAX)
                   19379: 
                   19380: #define        USHRT_MAX       ((unsigned short) ~0)
                   19381: #define        SHRT_MIN        _S_MIN(short)
                   19382: #define        SHRT_MAX        _S_MAX(short)
                   19383: 
                   19384: #define        UINT_MAX        ((unsigned int) ~0)
                   19385: #define        INT_MIN         _S_MIN(int)
                   19386: #define        INT_MAX         _S_MAX(int)
                   19387: 
                   19388: #define        ULONG_MAX       ((unsigned long) ~0)
                   19389: #define        LONG_MIN        _S_MIN(long)
                   19390: #define        LONG_MAX        _S_MAX(long)
                   19391: 
                   19392: ./pdksh/std/stdc/memcmp.c   644    653   1762         617  5243743544  12550 0ustar  hlu/* $Id: memcmp.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19393: 
                   19394: #include <string.h>
                   19395: 
                   19396: int
                   19397: memcmp(dap, sap, n)
                   19398:        const void *dap;
                   19399:        const void *sap;
                   19400:        register size_t n;
                   19401: {
                   19402:        register const unsigned char *dp = (unsigned char const *) dap;
                   19403:        register const unsigned char *sp = (unsigned char const *) sap;
                   19404: 
                   19405:        if (n++ > 0)
                   19406:                while (--n > 0)
                   19407:                        if (*dp++ != *sp++)
                   19408:                                return *--dp - *--sp; /* (int)? */
                   19409:        return 0;
                   19410: }
                   19411: 
                   19412: ./pdksh/std/stdc/memmove.c   644    653   1762         570  5243743545  12736 0ustar  hlu/* $Id: memmove.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19413: 
                   19414: #include "stdh.h"
                   19415: 
                   19416: void *
                   19417: memmove(dap, sap, n)
                   19418:        void *dap;
                   19419:        const void *sap;
                   19420:        register size_t n;
                   19421: {
                   19422:        register char *dp = dap, *sp = (void*) sap;
                   19423: 
                   19424:        if (n <= 0)
                   19425:                ;
                   19426:        else if (dp < sp)
                   19427:                do *dp++ = *sp++; while (--n > 0);
                   19428:        else if (dp > sp) {
                   19429:                dp += n;
                   19430:                sp += n;
                   19431:                do *--dp = *--sp; while (--n > 0);
                   19432:        }
                   19433:        return dap;
                   19434: }
                   19435: 
                   19436: 
                   19437: ./pdksh/std/stdc/setvbuf.c   644    653   1762        2077  5243743546  12774 0ustar  hlu/*
                   19438:  * PD ksh needs an ANSI-compatible setvbuf.
                   19439:  * if (buf == NULL) it must also allocate a buffer
                   19440:  * and arrange for fclose to deallocate it.
                   19441:  * the reason for doing setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ)
                   19442:  * in the shell is to avoid 4/8K buffers on BSD like systems.
                   19443:  */
                   19444: 
                   19445: /* $Id: setvbuf.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19446: 
                   19447: #include <stdlib.h>
                   19448: #include <stdio.h>
                   19449: 
                   19450: #if _BSD || _SYSV
                   19451: int
                   19452: setvbuf(f, buf, type, size)
                   19453:        register FILE *f;
                   19454:        char *buf;
                   19455:        int type;
                   19456:        size_t size;
                   19457: {
                   19458:        if ((f->_flag&_IOMYBUF) && f->_base != NULL)
                   19459:                free(f->_base);
                   19460:        f->_flag &= ~(_IOMYBUF|_IONBF|_IOFBF|_IOLBF);
                   19461:        switch (type) {
                   19462:          case _IONBF:
                   19463:                size = 0;
                   19464:                buf = NULL;
                   19465:                break;
                   19466:          case _IOLBF:
                   19467:          case _IOFBF:
                   19468:                if (size == 0)
                   19469:                        size = BUFSIZ;
                   19470: #if _V7
                   19471:                else if (size != BUFSIZ)
                   19472:                        return -1;
                   19473: #endif
                   19474:                if (buf == NULL) {
                   19475:                        buf = malloc(size);
                   19476:                        if (buf == NULL)
                   19477:                                return -1;
                   19478:                        f->_flag |= _IOMYBUF;
                   19479:                }
                   19480:                break;
                   19481:          default:
                   19482:                return -1;
                   19483:        }
                   19484:        f->_flag |= type;
                   19485:        f->_base = f->_ptr = buf;
                   19486:        f->_cnt = 0;
                   19487: #if _BSD
                   19488:        f->_bufsiz = size;
                   19489: #endif
                   19490: #if _SYSV
                   19491:        _bufend(f) = buf + size;
                   19492: #endif
                   19493:        return 0;
                   19494: }
                   19495: #endif
                   19496: 
                   19497: ./pdksh/std/stdc/sprintf.c   644    653   1762        1522  5243743641  12771 0ustar  hlu/*
                   19498:  * sprintf and vsprintf
                   19499:  */
                   19500: 
                   19501: /* $Id: sprintf.c,v 1.3 1992/05/12 09:31:01 sjg Exp $ */
                   19502: 
                   19503: #ifdef __STDC__
                   19504: #include <stdarg.h>
                   19505: #else
                   19506: #include <varargs.h>
                   19507: #endif
                   19508: #include <stdio.h>
                   19509: 
                   19510: #if _V7 || _BSD
                   19511: 
                   19512: int
                   19513: #ifdef __STDC__
                   19514: sprintf(char *s, const char *fmt, ...) {
                   19515: #else
                   19516: sprintf(va_alist) va_dcl
                   19517: {
                   19518:        char *s;
                   19519:        char *fmt;
                   19520: #endif
                   19521:        register va_list va;
                   19522:        int n;
                   19523: 
                   19524: #ifdef __STDC__
                   19525:        va_start(va, fmt);
                   19526: #else
                   19527:        va_start(va);
                   19528:        s = va_arg(va, char *);
                   19529:        fmt = va_arg(va, char *);
                   19530: #endif
                   19531:        n = vsprintf(s, fmt, va);
                   19532:        va_end(va);
                   19533:        return n;
                   19534: }
                   19535: 
                   19536: int
                   19537: #ifdef __STDC__
                   19538: vsprintf(char *s, const char *fmt, va_list va) {
                   19539: #else
                   19540: vsprintf(s, fmt, va)
                   19541:        char *s;
                   19542:        char *fmt;
                   19543:        va_list va;
                   19544: {
                   19545: #endif
                   19546:        int n;
                   19547:        static FILE siob;
                   19548: 
                   19549:        siob._flag = _IOWRT;
                   19550:        siob._base = siob._ptr = s;
                   19551:        siob._cnt = BUFSIZ;
                   19552:        siob._file = -1;
                   19553: 
                   19554:        n = vfprintf(&siob, fmt, va);
                   19555:        *siob._ptr = 0;
                   19556:        return n;
                   19557: }
                   19558: 
                   19559: #endif
                   19560: 
                   19561: ./pdksh/std/stdc/stdarg.h   644    653   1762        1331  5243743547  12600 0ustar  hlu/* $Id: stdarg.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19562: /* DON'T USE THIS IF YOUR COMPILER HAS ITS OWN!!! */
                   19563: 
                   19564: #ifndef _STDARG_H
                   19565: #define _STDARG_H
                   19566: 
                   19567: typedef char *va_list;
                   19568: 
                   19569: /* Amount of space required in an argument list for an arg of type TYPE.
                   19570:    TYPE may alternatively be an expression whose type is used.  */
                   19571: 
                   19572: #define __va_rounded_size(TYPE)  \
                   19573:   (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
                   19574: 
                   19575: #define va_start(AP, LASTARG)                                          \
                   19576:  (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
                   19577: 
                   19578: void va_end (va_list);         /* Defined in gnulib */
                   19579: #define va_end(AP)
                   19580: 
                   19581: #define va_arg(AP, TYPE)                                               \
                   19582:  (AP += __va_rounded_size (TYPE),                                      \
                   19583:   *((TYPE *) (AP - __va_rounded_size (TYPE))))
                   19584: 
                   19585: #endif /* _STDARG_H */
                   19586: ./pdksh/std/stdc/stddef.h   644    653   1762        1347  5243743547  12574 0ustar  hlu/* ANSI common definitions */
                   19587: 
                   19588: /* $Id: stddef.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19589: 
                   19590: #ifndef NULL
                   19591: #if __STDC__
                   19592: #define        NULL    (void*)0
                   19593: #else
                   19594: #define        NULL    0
                   19595: #endif
                   19596: #endif
                   19597: 
                   19598: #ifndef _STDDEF_H
                   19599: #define        _STDDEF_H
                   19600: 
                   19601: /* doesn't really belong here, but the library function need it */
                   19602: #ifndef ARGS
                   19603: # ifdef  __STDC__
                   19604: #   define ARGS(args) args
                   19605: # else
                   19606: #   define ARGS(args) ()
                   19607: #   ifdef VOID
                   19608: #     define void VOID
                   19609: #   endif
                   19610: #   define const
                   19611: #   define volatile
                   19612: # endif
                   19613: #endif
                   19614: 
                   19615: #ifdef HAVE_SYS_STDTYPES
                   19616: # include <sys/stdtypes.h>
                   19617: #else
                   19618: typedef unsigned size_t;               /* may need long */
                   19619: typedef int ptrdiff_t;
                   19620: #endif /* HAVE_SYS_STDTYPES */
                   19621: #define        offsetof(type,id) ((size_t)&((type*)NULL)->id)
                   19622: 
                   19623: extern int errno;              /* really belongs in <errno.h> */
                   19624: 
                   19625: #endif
                   19626: 
                   19627: ./pdksh/std/stdc/stdio.sed   644    653   1762        1324  5243743011  12746 0ustar  hlu/^#[  ]*include/d
                   19628: /^#[   ]*define[       ]*NULL/d
                   19629: /remove[       ]*([    ]*)/d
                   19630: /rename[       ]*([    ]*)/d
                   19631: /tmpfile[      ]*([    ]*)/d
                   19632: /tmpnam[       ]*([    ]*)/d
                   19633: /fopen[        ]*([    ]*)/d
                   19634: /freopen[      ]*([    ]*)/d
                   19635: /fdopen[       ]*([    ]*)/d
                   19636: /fflush[       ]*([    ]*)/d
                   19637: /fclose[       ]*([    ]*)/d
                   19638: /setbuf[       ]*([    ]*)/d
                   19639: /setvbuf[      ]*([    ]*)/d
                   19640: /fseek[        ]*([    ]*)/d
                   19641: /ftell[        ]*([    ]*)/d
                   19642: /rewind[       ]*([    ]*)/d
                   19643: /printf[       ]*([    ]*)/d
                   19644: /fprintf[      ]*([    ]*)/d
                   19645: /sprintf[      ]*([    ]*)/d
                   19646: /vprintf[      ]*([    ]*)/d
                   19647: /vfprintf[     ]*([    ]*)/d
                   19648: /vsprintf[     ]*([    ]*)/d
                   19649: /scanf[        ]*([    ]*)/d
                   19650: /fscanf[       ]*([    ]*)/d
                   19651: /sscanf[       ]*([    ]*)/d
                   19652: /fread[        ]*([    ]*)/d
                   19653: /frwrite[      ]*([    ]*)/d
                   19654: /fgetc[        ]*([    ]*)/d
                   19655: /fputc[        ]*([    ]*)/d
                   19656: /fgets[        ]*([    ]*)/d
                   19657: /fputs[        ]*([    ]*)/d
                   19658: /gets[         ]*([    ]*)/d
                   19659: /puts[         ]*([    ]*)/d
                   19660: ./pdksh/std/stdc/stdlib.h   644    653   1762        2110  5243743550  12563 0ustar  hlu/* ANSI utility functions */
                   19661: 
                   19662: /* $Id: stdlib.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19663: 
                   19664: #if ! _STDLIB_H
                   19665: #define        _STDLIB_H 1
                   19666: 
                   19667: #include <stddef.h>
                   19668: 
                   19669: double atof ARGS((const char *s));
                   19670: int    atoi ARGS((const char *s));
                   19671: long   atol ARGS((const char *s));
                   19672: double strtod ARGS((const char *s, char **));
                   19673: long   strtol ARGS((const char *s, char **, int base));
                   19674: unsigned long  strtoul ARGS((const char *s, char **, int base));
                   19675: int    rand ARGS((void));
                   19676: void   srand ARGS((unsigned int seed));
                   19677: void   *malloc ARGS((size_t size));
                   19678: void   *realloc ARGS((void *ptr, size_t size));
                   19679: void   *calloc ARGS((size_t n, size_t size));
                   19680: void   free ARGS((void *ptr));
                   19681: void   abort ARGS((void));
                   19682: int    atexit ARGS((void (*func)(void)));
                   19683: void   exit ARGS((int status));
                   19684: char   *getenv ARGS((const char *name));
                   19685: int    system ARGS((const char *cmd));
                   19686: void   *bsearch ARGS ((const void *key, const void *base, size_t n, size_t size,
                   19687:                       int (*compar)(const void *, const void *)));
                   19688: void   *qsort ARGS ((const void *base, size_t n, size_t size,
                   19689:                     int (*compar)(const void *, const void *)));
                   19690: #define        abs(a)  ((a) < 0 : -(a) : (a))
                   19691: 
                   19692: #endif
                   19693: 
                   19694: ./pdksh/std/stdc/strchr.c   644    653   1762         737  5243743551  12600 0ustar  hlu#include <string.h>
                   19695: /* $Id: strchr.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19696: 
                   19697: /*
                   19698:  * strchr - find first occurrence of a character in a string
                   19699:  */
                   19700: 
                   19701: char *                         /* found char, or NULL if none */
                   19702: strchr(s, charwanted)
                   19703: const char *s;
                   19704: register char charwanted;
                   19705: {
                   19706:        register const char *scan;
                   19707: 
                   19708:        /*
                   19709:         * The odd placement of the two tests is so NUL is findable.
                   19710:         */
                   19711:        for (scan = s; *scan != charwanted;)    /* ++ moved down for opt. */
                   19712:                if (*scan++ == '\0')
                   19713:                        return(NULL);
                   19714:        return(scan);
                   19715: }
                   19716: ./pdksh/std/stdc/strcmp.c   644    653   1762        1456  5243743552  12623 0ustar  hlu#include <string.h>
                   19717: /* $Id: strcmp.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19718: 
                   19719: /* Modified by Eric Gisin */
                   19720: 
                   19721: /*
                   19722:  * strcmp - compare string s1 to s2
                   19723:  */
                   19724: 
                   19725: int                            /* <0 for <, 0 for ==, >0 for > */
                   19726: strcmp(s1, s2)
                   19727: const char *s1;
                   19728: const char *s2;
                   19729: {
                   19730:        register const char *scan1;
                   19731:        register const char *scan2;
                   19732: #if 0                          /* some machines prefer int to char */
                   19733:        register int c1, c2;
                   19734: #else
                   19735:        register char c1, c2;
                   19736: #endif
                   19737: 
                   19738:        scan1 = s1;
                   19739:        scan2 = s2;
                   19740:        while ((c1 = *scan1++) == (c2 = *scan2++) && c1 != 0)
                   19741:                ;
                   19742: 
                   19743:        /*
                   19744:         * The following case analysis is necessary so that characters
                   19745:         * which look negative collate low against normal characters but
                   19746:         * high against the end-of-string NUL.
                   19747:         */
                   19748:        if (c1 == '\0' && c2 == '\0')
                   19749:                return(0);
                   19750:        else if (c1 == '\0')
                   19751:                return(-1);
                   19752:        else if (c2 == '\0')
                   19753:                return(1);
                   19754:        else
                   19755:                return(c1 - c2);
                   19756: }
                   19757: ./pdksh/std/stdc/strcspn.c   644    653   1762        1014  5243743554  12777 0ustar  hlu#include <string.h>
                   19758: /* $Id: strcspn.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19759: 
                   19760: /*
                   19761:  * strcspn - find length of initial segment of s consisting entirely
                   19762:  * of characters not from reject
                   19763:  */
                   19764: 
                   19765: size_t
                   19766: strcspn(s, reject)
                   19767: const char *s;
                   19768: const char *reject;
                   19769: {
                   19770:        register const char *scan;
                   19771:        register const char *rscan;
                   19772:        register size_t count;
                   19773: 
                   19774:        count = 0;
                   19775:        for (scan = s; *scan != '\0'; scan++) {
                   19776:                for (rscan = reject; *rscan != '\0';)   /* ++ moved down. */
                   19777:                        if (*scan == *rscan++)
                   19778:                                return(count);
                   19779:                count++;
                   19780:        }
                   19781:        return(count);
                   19782: }
                   19783: ./pdksh/std/stdc/string.h   644    653   1762        2401  5243743555  12620 0ustar  hlu/* ANSI string handling (missing wide char stuff) */
                   19784: /* $Id: string.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19785: 
                   19786: #if ! _STRING_H
                   19787: #define _STRING_H 1
                   19788: 
                   19789: #include <stddef.h>            /* define NULL and size_t */
                   19790: 
                   19791: #ifndef __GNUC__
                   19792: void   *memcpy ARGS((void *s1, const void *s2, size_t));
                   19793: int    memcmp ARGS((const void *s1, const void *s2, size_t));
                   19794: size_t strlen ARGS((const char *s));
                   19795: #endif
                   19796: void   *memmove ARGS((void *s1, const void *s2, size_t));
                   19797: void   *memchr ARGS((const void *s, int c, size_t));
                   19798: void   *memset ARGS((void *s, int c, size_t));
                   19799: char   *strcpy ARGS((char *s1, const char *s2));
                   19800: char   *strncpy ARGS((char *s1, const char *s2, size_t));
                   19801: char   *strcat ARGS((char *s1, const char *s2));
                   19802: char   *strncat ARGS((char *s1, const char *s2, size_t));
                   19803: int    strcmp ARGS((const char *s1, const char *s2));
                   19804: int    strncmp ARGS((const char *s1, const char *s2, size_t));
                   19805: char   *strchr ARGS((const char *s1, int c));
                   19806: char   *strrchr ARGS((const char *s1, int c));
                   19807: size_t strspn ARGS((const char *s1, const char *s2));
                   19808: size_t strcspn ARGS((const char *s1, const char *s2));
                   19809: char   *strpbrk ARGS((const char *s1, const char *s2));
                   19810: char   *strstr ARGS((const char *s1, const char *s2));
                   19811: char   *strtok ARGS((char *s1, const char *s2));
                   19812: char   *strerror ARGS((int errno));
                   19813: 
                   19814: #endif /* _STRING_H */
                   19815: 
                   19816: ./pdksh/std/stdc/strncat.c   644    653   1762         744  5243743556  12754 0ustar  hlu#include <string.h>
                   19817: /* $Id: strncat.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19818: 
                   19819: /*
                   19820:  * strncat - append at most n characters of string src to dst
                   19821:  */
                   19822: char *                         /* dst */
                   19823: strncat(dst, src, n)
                   19824: char *dst;
                   19825: const char *src;
                   19826: size_t n;
                   19827: {
                   19828:        register char *dscan;
                   19829:        register const char *sscan;
                   19830:        register size_t count;
                   19831: 
                   19832:        for (dscan = dst; *dscan != '\0'; dscan++)
                   19833:                continue;
                   19834:        sscan = src;
                   19835:        count = n;
                   19836:        while (*sscan != '\0' && --count >= 0)
                   19837:                *dscan++ = *sscan++;
                   19838:        *dscan++ = '\0';
                   19839:        return(dst);
                   19840: }
                   19841: ./pdksh/std/stdc/strncmp.c   644    653   1762        1503  5243743556  12776 0ustar  hlu#include <string.h>
                   19842: /* $Id: strncmp.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19843: 
                   19844: /*
                   19845:  * strncmp - compare at most n characters of string s1 to s2
                   19846:  */
                   19847: 
                   19848: int                            /* <0 for <, 0 for ==, >0 for > */
                   19849: strncmp(s1, s2, n)
                   19850: const char *s1;
                   19851: const char *s2;
                   19852: size_t n;
                   19853: {
                   19854:        register const char *scan1;
                   19855:        register const char *scan2;
                   19856:        register size_t count;
                   19857: 
                   19858:        scan1 = s1;
                   19859:        scan2 = s2;
                   19860:        count = n;
                   19861:        while (--count >= 0 && *scan1 != '\0' && *scan1 == *scan2) {
                   19862:                scan1++;
                   19863:                scan2++;
                   19864:        }
                   19865:        if (count < 0)
                   19866:                return(0);
                   19867: 
                   19868:        /*
                   19869:         * The following case analysis is necessary so that characters
                   19870:         * which look negative collate low against normal characters but
                   19871:         * high against the end-of-string NUL.
                   19872:         */
                   19873:        if (*scan1 == '\0' && *scan2 == '\0')
                   19874:                return(0);
                   19875:        else if (*scan1 == '\0')
                   19876:                return(-1);
                   19877:        else if (*scan2 == '\0')
                   19878:                return(1);
                   19879:        else
                   19880:                return(*scan1 - *scan2);
                   19881: }
                   19882: ./pdksh/std/stdc/strncpy.c   644    653   1762         723  5243743557  12776 0ustar  hlu#include <string.h>
                   19883: /* $Id: strncpy.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19884: 
                   19885: /*
                   19886:  * strncpy - copy at most n characters of string src to dst
                   19887:  */
                   19888: char *                         /* dst */
                   19889: strncpy(dst, src, n)
                   19890: char *dst;
                   19891: const char *src;
                   19892: size_t n;
                   19893: {
                   19894:        register char *dscan;
                   19895:        register const char *sscan;
                   19896:        register size_t count;
                   19897: 
                   19898:        dscan = dst;
                   19899:        sscan = src;
                   19900:        count = n;
                   19901:        while (--count >= 0 && (*dscan++ = *sscan++) != '\0')
                   19902:                continue;
                   19903:        while (--count >= 0)
                   19904:                *dscan++ = '\0';
                   19905:        return(dst);
                   19906: }
                   19907: ./pdksh/std/stdc/strpbrk.c   644    653   1762         744  5243743560  12760 0ustar  hlu#include <string.h>
                   19908: /* $Id: strpbrk.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19909: 
                   19910: /*
                   19911:  * strpbrk - find first occurrence of any char from breakat in s
                   19912:  */
                   19913: 
                   19914: char *                         /* found char, or NULL if none */
                   19915: strpbrk(s, breakat)
                   19916: const char *s;
                   19917: const char *breakat;
                   19918: {
                   19919:        register const char *sscan;
                   19920:        register const char *bscan;
                   19921: 
                   19922:        for (sscan = s; *sscan != '\0'; sscan++) {
                   19923:                for (bscan = breakat; *bscan != '\0';)  /* ++ moved down. */
                   19924:                        if (*sscan == *bscan++)
                   19925:                                return(sscan);
                   19926:        }
                   19927:        return(NULL);
                   19928: }
                   19929: ./pdksh/std/stdc/strrchr.c   644    653   1762         730  5243743560  12753 0ustar  hlu#include <string.h>
                   19930: /* $Id: strrchr.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19931: 
                   19932: /*
                   19933:  * strrchr - find last occurrence of a character in a string
                   19934:  */
                   19935: 
                   19936: char *                         /* found char, or NULL if none */
                   19937: strrchr(s, charwanted)
                   19938: const char *s;
                   19939: register char charwanted;
                   19940: {
                   19941:        register const char *scan;
                   19942:        register const char *place;
                   19943: 
                   19944:        place = NULL;
                   19945:        for (scan = s; *scan != '\0'; scan++)
                   19946:                if (*scan == charwanted)
                   19947:                        place = scan;
                   19948:        if (charwanted == '\0')
                   19949:                return(scan);
                   19950:        return(place);
                   19951: }
                   19952: ./pdksh/std/stdc/time.h   644    653   1762        2020  5243743562  12243 0ustar  hlu/* time, time/date conversion */
                   19953: /* $Id: time.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   19954: 
                   19955: #if ! _TIME_H
                   19956: #define        _TIME_H 1
                   19957: 
                   19958: #include <stddef.h>            /* need size_t */
                   19959: 
                   19960: #ifndef HAVE_SYS_STDTYPES
                   19961: #ifndef _TIME_T
                   19962: typedef long time_t;
                   19963: #endif
                   19964: typedef long clock_t;          /* seconds/CLK_TCK */
                   19965: #endif
                   19966: 
                   19967: #if _V7 || _SYSV
                   19968: #define        CLK_TCK 60              /* todo: get from <sys/param.h> */
                   19969: #endif
                   19970: 
                   19971: #if _BSD
                   19972: #define        CLK_TCK 100
                   19973: #endif
                   19974: 
                   19975: #if _ST
                   19976: #define        CLK_TCK 200             /* ST system clock */
                   19977: #endif
                   19978: 
                   19979: struct tm {
                   19980:        int     tm_sec, tm_min, tm_hour;
                   19981:        int     tm_mday, tm_mon, tm_year, tm_wday, tm_yday;
                   19982:        int     tm_isdst;
                   19983:        long    tm_gmtoff;      /* BSD */
                   19984:        char   *tm_zone;        /* BSD */
                   19985: };
                   19986: 
                   19987: clock_t        clock ARGS((void));
                   19988: time_t time ARGS((time_t *tp));
                   19989: #define        difftime(t1, t2)        (double)((t2)-(t1))
                   19990: time_t mktime ARGS((struct tm *tmp));
                   19991: char   *asctime ARGS((const struct tm *tmp));
                   19992: char   *ctime ARGS((const time_t *tp));
                   19993: struct tm *gmtime ARGS((const time_t *tp));
                   19994: struct tm *localtime ARGS((const time_t *tp));
                   19995: size_t strftime ARGS((char *buf, size_t len, const char *fmt, const struct tm *tmp));
                   19996: 
                   19997: #endif
                   19998: 
                   19999: ./pdksh/std/stdc/strspn.c   644    653   1762        1033  5243743560  12632 0ustar  hlu#include <string.h>
                   20000: /* $Id: strspn.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20001: 
                   20002: /*
                   20003:  * strspn - find length of initial segment of s consisting entirely
                   20004:  * of characters from accept
                   20005:  */
                   20006: 
                   20007: size_t
                   20008: strspn(s, accept)
                   20009: const char *s;
                   20010: const char *accept;
                   20011: {
                   20012:        register const char *sscan;
                   20013:        register const char *ascan;
                   20014:        register size_t count;
                   20015: 
                   20016:        count = 0;
                   20017:        for (sscan = s; *sscan != '\0'; sscan++) {
                   20018:                for (ascan = accept; *ascan != '\0'; ascan++)
                   20019:                        if (*sscan == *ascan)
                   20020:                                break;
                   20021:                if (*ascan == '\0')
                   20022:                        return(count);
                   20023:                count++;
                   20024:        }
                   20025:        return(count);
                   20026: }
                   20027: ./pdksh/std/stdc/strstr.c   644    653   1762        1260  5243743561  12645 0ustar  hlu#ifndef lint
                   20028: static char *RCSid = "$Id: strstr.c,v 1.2 1992/04/25 00:58:50 sjg Exp $";
                   20029: #endif
                   20030: 
                   20031: #include "stdh.h"
                   20032: 
                   20033: /*
                   20034:  * strstr - find first occurrence of wanted in s
                   20035:  */
                   20036: 
                   20037: char *                         /* found string, or NULL if none */
                   20038: strstr(s, wanted)
                   20039: const char *s;
                   20040: const char *wanted;
                   20041: {
                   20042:        register const char *scan;
                   20043:        register size_t len;
                   20044:        register char firstc;
                   20045: 
                   20046:        /*
                   20047:         * The odd placement of the two tests is so "" is findable.
                   20048:         * Also, we inline the first char for speed.
                   20049:         * The ++ on scan has been moved down for optimization.
                   20050:         */
                   20051:        firstc = *wanted;
                   20052:        len = strlen(wanted);
                   20053:        for (scan = s; *scan != firstc || strncmp(scan, wanted, len) != 0; )
                   20054:                if (*scan++ == '\0')
                   20055:                        return(NULL);
                   20056:        return(scan);
                   20057: }
                   20058: ./pdksh/std/stdc/strtok.c   644    653   1762        2214  5243743561  12632 0ustar  hlu#include <string.h>
                   20059: /* $Id: strtok.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20060: 
                   20061: /*
                   20062:  * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
                   20063:  * where tokens are nonempty strings separated by runs of
                   20064:  * chars from delim.  Writes NULs into s to end tokens.  delim need not
                   20065:  * remain constant from call to call.
                   20066:  */
                   20067: 
                   20068: static char *scanpoint = NULL;
                   20069: 
                   20070: char *                         /* NULL if no token left */
                   20071: strtok(s, delim)
                   20072: char *s;
                   20073: register const char *delim;
                   20074: {
                   20075:        register char *scan;
                   20076:        char *tok;
                   20077:        register const char *dscan;
                   20078: 
                   20079:        if (s == NULL && scanpoint == NULL)
                   20080:                return(NULL);
                   20081:        if (s != NULL)
                   20082:                scan = s;
                   20083:        else
                   20084:                scan = scanpoint;
                   20085: 
                   20086:        /*
                   20087:         * Scan leading delimiters.
                   20088:         */
                   20089:        for (; *scan != '\0'; scan++) {
                   20090:                for (dscan = delim; *dscan != '\0'; dscan++)
                   20091:                        if (*scan == *dscan)
                   20092:                                break;
                   20093:                if (*dscan == '\0')
                   20094:                        break;
                   20095:        }
                   20096:        if (*scan == '\0') {
                   20097:                scanpoint = NULL;
                   20098:                return(NULL);
                   20099:        }
                   20100: 
                   20101:        tok = scan;
                   20102: 
                   20103:        /*
                   20104:         * Scan token.
                   20105:         */
                   20106:        for (; *scan != '\0'; scan++) {
                   20107:                for (dscan = delim; *dscan != '\0';)    /* ++ moved down. */
                   20108:                        if (*scan == *dscan++) {
                   20109:                                scanpoint = scan+1;
                   20110:                                *scan = '\0';
                   20111:                                return(tok);
                   20112:                        }
                   20113:        }
                   20114: 
                   20115:        /*
                   20116:         * Reached end of string.
                   20117:         */
                   20118:        scanpoint = NULL;
                   20119:        return(tok);
                   20120: }
                   20121: ./pdksh/std/stdc/types.h   644    653   1762         652  5243743562  12442 0ustar  hlu/* work around multiple typedefs in stddef.h and sys/types.h */
                   20122: /* $Id: types.h,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20123: 
                   20124: #include <stddef.h>            /* defines size_t and ptrdiff_t */
                   20125: #include <time.h>              /* defines time_t and clock_t */
                   20126: 
                   20127: /* "inhibit" the typedefs in sys/types.h */
                   20128: #define size_t _size_t
                   20129: #define        time_t _time_t
                   20130: #define        clock_t _clock_t
                   20131: #include "/./usr/include/sys/types.h"
                   20132: #undef size_t
                   20133: #undef time_t
                   20134: #undef clock_t
                   20135: 
                   20136: ./pdksh/std/stdc/memchr.c   644    653   1762         412  5243743544  12536 0ustar  hlu/* $Id: memchr.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20137: 
                   20138: #include <string.h>
                   20139: 
                   20140: void *
                   20141: memchr(ap, c, n)
                   20142:        const void *ap;
                   20143:        register int c;
                   20144:        register size_t n;
                   20145: {
                   20146:        register char *p = ap;
                   20147: 
                   20148:        if (n++ > 0)
                   20149:                while (--n > 0)
                   20150:                        if (*p++ == c)
                   20151:                                return --p;
                   20152:        return NULL;
                   20153: }
                   20154: 
                   20155: ./pdksh/std/stdc/memcpy.c   644    653   1762         415  5243743545  12561 0ustar  hlu/* $Id: memcpy.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20156: 
                   20157: #include <string.h>
                   20158: 
                   20159: void *
                   20160: memcpy(dap, sap, n)
                   20161:        void *dap;
                   20162:        const void *sap;
                   20163:        register size_t n;
                   20164: {
                   20165:        register char *dp = dap, *sp = (void*) sap;
                   20166: 
                   20167:        if (n++ > 0)
                   20168:                while (--n > 0)
                   20169:                        *dp++ = *sp++;
                   20170:        return dap;
                   20171: }
                   20172: 
                   20173: ./pdksh/std/stdc/memset.c   644    653   1762         355  5243743545  12564 0ustar  hlu/* $Id: memset.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20174: 
                   20175: #include <string.h>
                   20176: 
                   20177: void *
                   20178: memset(ap, c, n)
                   20179:        void *ap;
                   20180:        register int c;
                   20181:        register size_t n;
                   20182: {
                   20183:        register char *p = ap;
                   20184: 
                   20185:        if (n++ > 0)
                   20186:                while (--n > 0)
                   20187:                        *p++ = c;
                   20188:        return ap;
                   20189: }
                   20190: 
                   20191: ./pdksh/std/stdc/strcat.c   644    653   1762         572  5243743551  12570 0ustar  hlu#include <string.h>
                   20192: /* $Id: strcat.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20193: 
                   20194: /*
                   20195:  * strcat - append string src to dst
                   20196:  */
                   20197: char *                         /* dst */
                   20198: strcat(dst, src)
                   20199: char *dst;
                   20200: const char *src;
                   20201: {
                   20202:        register char *dscan;
                   20203:        register const char *sscan;
                   20204: 
                   20205:        for (dscan = dst; *dscan != '\0'; dscan++)
                   20206:                continue;
                   20207:        sscan = src;
                   20208:        while ((*dscan++ = *sscan++) != '\0')
                   20209:                continue;
                   20210:        return(dst);
                   20211: }
                   20212: ./pdksh/std/stdc/strcpy.c   644    653   1762         516  5243743553  12614 0ustar  hlu#include <string.h>
                   20213: /* $Id: strcpy.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20214: 
                   20215: /*
                   20216:  * strcpy - copy string src to dst
                   20217:  */
                   20218: char *                         /* dst */
                   20219: strcpy(dst, src)
                   20220: char *dst;
                   20221: const char *src;
                   20222: {
                   20223:        register char *dscan;
                   20224:        register const char *sscan;
                   20225: 
                   20226:        dscan = dst;
                   20227:        sscan = src;
                   20228:        while ((*dscan++ = *sscan++) != '\0')
                   20229:                continue;
                   20230:        return(dst);
                   20231: }
                   20232: ./pdksh/std/stdc/strerror.c   644    653   1762         600  5243743554  13145 0ustar  hlu#include <string.h>
                   20233: /* $Id: strerror.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20234: 
                   20235: /*
                   20236:  * strerror - map error number to descriptive string
                   20237:  *
                   20238:  * This version is obviously somewhat Unix-specific.
                   20239:  */
                   20240: char *
                   20241: strerror(errno)
                   20242: int errno;
                   20243: {
                   20244:        extern int sys_nerr;
                   20245:        extern char *sys_errlist[];
                   20246: 
                   20247:        if (errno > 0 && errno < sys_nerr)
                   20248:                return(sys_errlist[errno]);
                   20249:        else
                   20250:                return("unknown error");
                   20251: }
                   20252: ./pdksh/std/stdc/strlen.c   644    653   1762         451  5243743555  12577 0ustar  hlu#include <string.h>
                   20253: /* $Id: strlen.c,v 1.2 1992/04/25 08:19:26 sjg Exp $ */
                   20254: 
                   20255: /*
                   20256:  * strlen - length of string (not including NUL)
                   20257:  */
                   20258: size_t
                   20259: strlen(s)
                   20260: const char *s;
                   20261: {
                   20262:        register const char *scan;
                   20263:        register size_t count;
                   20264: 
                   20265:        count = 0;
                   20266:        scan = s;
                   20267:        while (*scan++ != '\0')
                   20268:                count++;
                   20269:        return(count);
                   20270: }
                   20271: ./pdksh/std/stdc/ChangeLog   644    653   1762         644  5243743637  12703 0ustar  hluThu May  7 20:36:40 1992  Simon J. Gerraty  (sjg@zen)
                   20272: 
                   20273:        * fprintf.c: avoid use of #if __STDC__ some compilers don't handle it.
                   20274: 
                   20275:        * vprintf.c: avoid side effects from putc() macro!
                   20276: 
                   20277: Sat Apr 25 14:52:01 1992  Simon J. Gerraty  (sjg@zen)
                   20278: 
                   20279:        * Added RCS keys to sources.
                   20280: 
                   20281: Mon Nov 25 13:19:01 1991  Simon J. Gerraty  (sjg at zen)
                   20282: 
                   20283:        * Added all source modules to Makefile, but most remain commented
                   20284:        out as they are untested.
                   20285: 
                   20286: ./pdksh/std/Makefile   644    653   1762        1563  5243743530  11645 0ustar  hlu#
                   20287: # Makefile for the compatibility libraries
                   20288: #
                   20289: # $Id: Makefile,v 1.2 1992/04/25 08:18:26 sjg Exp $
                   20290: #
                   20291: 
                   20292: SHELL = /bin/sh
                   20293: MAKE  = make
                   20294: 
                   20295: #CONFIG = -D_SYSV
                   20296: CONFIG = -D_BSD
                   20297: 
                   20298: LN = ln
                   20299: 
                   20300: libs:  h libstdc.a libposix.a
                   20301: 
                   20302: h:
                   20303:        mkdir h
                   20304:        ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' clobber link )
                   20305:        ( cd posix  ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' clobber link )
                   20306:        ( cd ../sh ;  $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' link )
                   20307: 
                   20308: libstdc.a: FORCED
                   20309:        ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' all )
                   20310: 
                   20311: libposix.a: FORCED
                   20312:        ( cd posix ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' all )
                   20313: 
                   20314: clean:
                   20315:        -rm -f *.out
                   20316:        ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ )
                   20317:        ( cd posix  ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ )
                   20318: 
                   20319: clobber:
                   20320:        -rm -rf h *.a
                   20321:        ( cd stdc ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ )
                   20322:        ( cd posix  ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ )
                   20323: 
                   20324: FORCED:
                   20325: ./pdksh/std/mklinks   644    653   1762         231  5243743473  11555 0ustar  hlu:
                   20326: # Make links 
                   20327: # we do it this way so that we can support symlinks
                   20328: # easily.
                   20329: 
                   20330: src=`pwd`
                   20331: cd $1
                   20332: shift
                   20333: LN="${LN:-ln}"
                   20334: 
                   20335: for f in $*
                   20336: do
                   20337:   $LN $src/$f .
                   20338: done
                   20339: ./pdksh/PATCHDATES   644    653   1762         167  5243743672  10744 0ustar  hlu# PD ksh Version 4
                   20340: 09-Nov-91
                   20341: 10-Nov-91
                   20342: 25-Nov-91
                   20343: 25-Apr-92
                   20344: 26-Apr-92
                   20345: 27-Apr-92
                   20346: 12-May-92
                   20347: 02-Aug-92
                   20348: 12-Aug-92
                   20349: 25-Apr-92
                   20350: ./pdksh/ksh.1   644    653   1762      101151  5243743650  10317 0ustar  hlu.\" $Id: ksh.1,v 1.2 1992/08/10 11:59:15 sjg Exp $
                   20351: .nr OJ 1 \" Job Control
                   20352: .nr OE 1 \" Command Editing
                   20353: .nr OB 1 \" BSD enhanced ulimit options
                   20354: .ds OK [\|
                   20355: .ds CK \|]
                   20356: .TH KSH 1 "July 1992"
                   20357: .SH NAME
                   20358: ksh \- Bourne / Korn Shell (Public Domain)
                   20359: .SH SYNOPSIS
                   20360: \fBksh\fP
                   20361: [\fB\-st\fP] [\fB\-c\fP \fIcommand\fP]
                   20362: [\fIfile\fP [\fIargument ...\fP]]
                   20363: .SH INTRODUCTION
                   20364: This document only summarizes the System V, release 2 shell features.
                   20365: All of the System V features except for ``restricted mode''
                   20366: are implemented.
                   20367: See also the BUGS section.
                   20368: .LP
                   20369: Features of the Korn shell are described in more detail.
                   20370: Only a subset of the Korn shell features are currently implemented.
                   20371: .SH DESCRIPTION
                   20372: .SS Command syntax
                   20373: The ``#'' character begins a one-line comment,
                   20374: unless the ``#'' occurs inside a word.
                   20375: The tokens ``;'', ``|'', ``&'', ``;;'', ``||'', ``&&'', ``('', and ``)''
                   20376: stand by themselves.
                   20377: A \fIword\fP is a sequence of any other non-whitespace characters,
                   20378: which may also contain quoted strings
                   20379: (quote character are ``\''', ``"'', ``\`'',
                   20380: or a matching ``${ }'' or ``$( )'' pair).
                   20381: A \fIname\fP is an unquoted word made up of letters, digits, or ``_''.
                   20382: Any number of whitespace characters (space and tab) may separate words and tokens.
                   20383: .LP
                   20384: In the following syntax, { ... }? indicates an optional thing,
                   20385: { ... }* indicates zero or more repetitions, { ... | ... } indicates alternatives.
                   20386: .de S
                   20387: .br
                   20388: \\$1
                   20389: .br
                   20390: ..
                   20391: .IP statement:
                   20392: .S "\fB(\fP list \fB)\fP"
                   20393: .S "\fB{\fP list \fB;\fP \fB}\fP"
                   20394: .S "\fBfor\fP name { \fBin\fP { word }* }? \fBdo\fP list \fB;\fP \fBdone\fP"
                   20395: .S "\fBselect\fP name { \fBin\fP { word }* }? \fBdo\fP list \fB;\fP \fBdone\fP"
                   20396: .S "{ \fBwhile\fP | \fBuntil\fP } list \fB;\fP \fBdo\fP list \fB;\fP \fBdone\fP"
                   20397: .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"
                   20398: .S "\fBcase\fP name \fBin\fP { \fB(\fP word { \fB|\fP word } \fB)\fP list \fB;;\fP }* \fBesac\fP"
                   20399: .S "\fBfunction\fP name \fB{\fP list \fB;\fP \fB}\fP"
                   20400: .S "name \fB() {\fP list \fB;\fP \fB}\fP"
                   20401: .S "\fBtime\fP pipe"
                   20402: The opening parenthesis of the pattern is optional. 
                   20403: Redirection may occur at the beginning or end of a statement.
                   20404: .IP command:
                   20405: .S "{ name=word }* { word }*"
                   20406: Redirection may occur anywhere in a command.
                   20407: .IP list:
                   20408: .S "cond"
                   20409: .S "cond \fB;\fP list"
                   20410: .S "cond \fB&\fP list"
                   20411: .IP cond:
                   20412: .S "pipe"
                   20413: .S "pipe \fB&&\fP cond"
                   20414: .S "pipe \fB||\fP cond"
                   20415: .IP pipe:
                   20416: .S "statement { \fB|\fP statement }*"
                   20417: .SS The select statement
                   20418: The \fBselect\fP statement provides an automatic method of presenting the
                   20419: user with a menu selection from several options.
                   20420: The \fIwords\fP given in the list are printed on standard error, each
                   20421: preceded by a number.
                   20422: Typing the number on standard input sets the variable \fIname\fP to the
                   20423: word that was selected.
                   20424: The data that was typed is preserved in a variable called REPLY.
                   20425: The contents of the loop are then executed using the selected value.
                   20426: A new prompt PS3 is used to indicate that a number should be typed in
                   20427: to choose a value from the menu.
                   20428: .LP
                   20429: Menus will continue to be presented until an interrupt is received or
                   20430: end-of-file is typed on input.
                   20431: .SS Alias expansion
                   20432: Alias expansion occurs when the first word of a
                   20433: statement is a defined alias,
                   20434: except when that alias is already being expanded.
                   20435: It also occurs after the expansion of an alias whose
                   20436: definition ends with a space.
                   20437: .SS Alternation
                   20438: Csh provides a filename expansion method known as alternation.
                   20439: This has been added into this version of ksh.
                   20440: When performing filename subsitution, you can get the shell to create
                   20441: a set of strings for you. For example, `exampl{a,b,c,d,e}' will expand
                   20442: to ``exampla examplb examplc exampld example''.
                   20443: A comma separated set of strings in curly braces 
                   20444: will be expanded into a set of strings that are passed into the command.
                   20445: The strings are not sorted.
                   20446: .SS Shell variables
                   20447: The following standard special variables exist:
                   20448: \fB!\fP, \fB#\fP, \fB$\fP, \fB\-\fP, \fB?\fP.
                   20449: .IP "_"
                   20450: In interactive use this parameter is set to the last word of
                   20451: the previous command.  When a command is executed this parameter
                   20452: is set to the full path of the command and placed in the environment
                   20453: for the command.  See also \fBMAILPATH\fP.
                   20454: .IP CDPATH
                   20455: The search path for the \fIcd\fP command.
                   20456: .IP ENV
                   20457: If this variable is set at start-up
                   20458: (after any profile files are executed),
                   20459: the expanded value is used as shell start-up file.
                   20460: It typically contains function and alias definitions.
                   20461: .IP FCEDIT
                   20462: The editor used by the \fIfc\fP command.
                   20463: During startup the shell checks the value of \fBFCEDIT\fP, 
                   20464: \fBEDITOR\fP and finally \fBVISUAL\fP to try and determin what
                   20465: command line edit mode to use.  Note that this is not strictly
                   20466: ksh compatible behaviour.
                   20467: .IP COLUMNS
                   20468: The width to use for the commandline editing (emacs mode only).
                   20469: .IP HISTFILE
                   20470: The name of the file used to store history.
                   20471: If defined, history will be loaded from this file on startup.
                   20472: Also, several invocations of the shell running on the same machine
                   20473: will share history if their HISTFILE variables all point at the same file.
                   20474: .IP HISTSIZE
                   20475: The number of commands normally stored for history, default 128.
                   20476: .IP HOME
                   20477: The default directory for the \fIcd\fP command.
                   20478: .IP IFS
                   20479: \fIInternal field separator\fP,
                   20480: used during substitution and the \fIread\fP command.
                   20481: .IP MAIL
                   20482: If set, the user will be informed of the arrival of mail
                   20483: in the named file.  This variable is ignored if
                   20484: the \fBMAILPATH\fP variable is set.
                   20485: .IP MAILCHECK
                   20486: How often, in seconds, the shell will check for mail in the
                   20487: file(s) specified by \fBMAIL\fP or \fBMAILPATH\fP.  If 0,
                   20488: the shell checks before each prompt.  The default is 600
                   20489: seconds.
                   20490: .IP MAILPATH
                   20491: A list of files to be checked for mail.  The list is colon
                   20492: separated, and each file may be followed by a \fB?\fP and
                   20493: a message to be printed if new mail has arrived.  Command
                   20494: and parameter substitution is performed on the message, and
                   20495: the parameter \fB$_\fP is set to the name of the file.
                   20496: The default message is ``you have mail in $_''.
                   20497: .IP PATH
                   20498: The search path for executable commands and \fB.\fP'd files.
                   20499: .IP PPID
                   20500: The process number of the parent of the shell.
                   20501: .IP "PS1 PS2"
                   20502: \fBPS1\fP is the primary prompt for interactive shells.
                   20503: Dollar substitution is performed, and \fB!\fP is replaced
                   20504: with the command number (see \fIfc\fP).
                   20505: .IP "PWD OLDPWD"
                   20506: The current and previous working directories.
                   20507: .IP RANDOM
                   20508: A random integer.  The random number generator may be seeded
                   20509: by assigning an integer value to this variable.
                   20510: .IP SECONDS
                   20511: The number of seconds since the shell timer was started or
                   20512: reset.  Assigning an integer value to this variable resets
                   20513: the timer.
                   20514: .SS Substitution
                   20515: In addition to the System Vr2 substitutions,
                   20516: the following are available.
                   20517: .IP "$(command)"
                   20518: Like `command`, but no escapes are recognized.
                   20519: .IP "$(<file)"
                   20520: Equivalent to $(cat file), but without forking.
                   20521: .IP "${#var}"
                   20522: The length of the string value of \fIvar\fP,
                   20523: or the number of arguments if \fIvar\fP is \fB*\fP or \fB@\fP.
                   20524: .IP "${var#pattern} ${var##pattern}"
                   20525: If \fIpattern\fP matches the beginning of the value of \fIvar\fP,
                   20526: the matched text is deleted from the result of substitution.
                   20527: A single \fB#\fP results in the shortest match,
                   20528: two \fB#\fP's results in the longest match.
                   20529: .IP "${var%pattern} ${var%%pattern}"
                   20530: Like \fB#\fP substition, but deleting from the end of the value.
                   20531: .SS Expressions
                   20532: Expressions can be used with the \fBlet\fP command,
                   20533: as numeric arguments to the \fBtest\fP command,
                   20534: and as the value of an assignment to an integer variable.
                   20535: .LP
                   20536: Expression may contain alpha-numeric variable identifiers and integer constants
                   20537: and may be combined with the following operators:
                   20538: .IP "== != <= < > >= + - * / % ! ( )"
                   20539: .SS Command execution
                   20540: After evaluation of keyword assignments and arguments,
                   20541: the type of command is determined.
                   20542: A command may execute a shell function, a shell built-in,
                   20543: or an executable file.
                   20544: .LP
                   20545: Any keyword assignments are then performed according to
                   20546: the type of command.
                   20547: In function calls assignments are local to the function.
                   20548: Assignments in built-in commands marked with a \(dg persist,
                   20549: otherwise they are temporary.
                   20550: Assignments in executable commands are exported to the sub-process
                   20551: executing the command.
                   20552: .LP
                   20553: Even on systems where the exec() family does not support #!
                   20554: notation for scripts, ksh can be configured to fake it.
                   20555: .LP
                   20556: There are several built-in commands.
                   20557: .IP ":"
                   20558: Only expansion and assignment are performed.
                   20559: This is the default if a command has no arguments.
                   20560: .IP ". \fIfile\fP"
                   20561: Execute the commands in \fIfile\fP without forking.
                   20562: The file is searched in the directories of $PATH.
                   20563: Passing arguments is not implemented.
                   20564: .IP "alias [\fIname\fB=\fIvalue\fI ...]\fR"
                   20565: Without arguments, \fBalias\fP lists all aliases and their values.
                   20566: For any name without a value, its value is listed.
                   20567: Any name with a value defines an alias, see "Alias Expansion" above.
                   20568: Korn's tracked aliases are not implemented,
                   20569: but System V command hashing is (see "hash").
                   20570: .IP "alias -d [\fIname\fB=\fIvalue\fI ...]\fR"
                   20571: Directory aliases for tilde expansion, eg.
                   20572: .br
                   20573: alias -d fac=/usr/local/usr/facilities
                   20574: .br
                   20575: cd ~fac/bin
                   20576: .IP "break [\fIlevels\fP]"
                   20577: .IP "builtin \fIcommand arg ...\fP"
                   20578: \fICommand\fP is executed as a built-in command.
                   20579: .IP "cd [\fIpath\fP]"
                   20580: Set the working directory to \fIpath\fP.  If the parameter
                   20581: CDPATH is set, it lists the search path for the directory
                   20582: containing \fIpath\fP.  A null path means the current directory.
                   20583: If \fIpath\fP is missing, the home directory ($HOME) is used.
                   20584: If \fIpath\fP is \fB\-\fP, the previous working directory is used.
                   20585: If \fIpath\fP is \fB..\fP, the shell changes directory to the
                   20586: parent directory, as determined from the value of PWD.
                   20587: The PWD and OLDPWD variables are reset.
                   20588: .IP "cd \fIold new\fP"
                   20589: The string \fInew\fP is substituted for \fIold\fP in the current
                   20590: directory, and the shell attempts to change to the new directory.
                   20591: .IP "continue [\fIlevels\fP]"
                   20592: .IP "echo ..."
                   20593: \fIEcho\fP is replaced with the alias echo='print' in the Korn shell.
                   20594: .IP "eval \fIcommand ...\fP"
                   20595: .IP "exec \fIcommand arg ...\fP"
                   20596: The executable command is executed without forking.
                   20597: If no arguments are given, any IO redirection is permanent.
                   20598: .IP "exit [\fIstatus\fP]"
                   20599: .IP "fc [\fB\-e\fP \fIeditor\fP] [\fB\-lnr\fP] [\fIfirst\fP [\fIlast\fP]]"
                   20600: \fIFirst\fP and \fIlast\fP select commands.
                   20601: Commands can be selected by history number,
                   20602: or a string specifing the most recent command starting with that string.
                   20603: The \fB\-l\fP option lists the command on stdout,
                   20604: and \fB\-n\fP inhibits the default command numbers.
                   20605: The \fB\-r\fP option reverses the order of the list.
                   20606: Without \fB\-l\fP, the selected commands can be edited by
                   20607: the editor specified with the \fB\-e\fP option, or if no \fB\-e\fP
                   20608: is specified,
                   20609: the \fB$FCEDIT\fP editor, then executed by the shell.
                   20610: .IP "fc \fB\-e \-\fP [\fB\-g\fP] [\fIold\fB=\fInew\fR] [\fIcommand\fP]"
                   20611: Re-execute the selected command (the previous command by default)
                   20612: after performing the optional substitution of \fIold\fP with \fInew\fP.
                   20613: If \fB\-g\fP is specified, all occurrences of \fIold\fP are
                   20614: replaced with \fInew\fP.
                   20615: This command is usually accessed with the predefined alias
                   20616: r=``fc \-e \-''.
                   20617: .IP "getopts"
                   20618: See the attached manual page.
                   20619: .IP "hash [\fB\-r\fP] [\fIname ...\fP]"
                   20620: Without arguments, any hashed executable command pathnames are listed.
                   20621: The \fB\-r\fP flag causes all hashed commands to be removed.
                   20622: Each \fIname\fP is searched as if it were a command name
                   20623: and added to the hash table if it is an executable command.
                   20624: .IP "kill [\fB\-\fIsignal\fR] \fIprocess\fP ..."
                   20625: Send a signal (TERM by default) to the named process.
                   20626: The signal may be specified as a number or a mnemonic from <signal.h>
                   20627: with the SIG prefix removed.
                   20628: .IP "let [\fIexpression ...\fP]"
                   20629: Each expression is evaluated, see "Expressions" above.
                   20630: A zero status is returned if the last expression evaluates
                   20631: to a non-zero value, otherwise a non-zero status is returned.
                   20632: Since may expressions need to be quoted, \fI(( expr ))\fP is
                   20633: syntactic sugar for \fIlet "expr"\fP.
                   20634: .IP "print [\fB\-nreu\fIn\fR] [\fIargument ...\fP]"
                   20635: \fBPrint\fP prints its arguments on the standard output,
                   20636: separated by spaces, and terminated with a newline.
                   20637: The \fB\-n\fP option eliminates the newline.
                   20638: .IP
                   20639: By default, certain C escapes are translated.
                   20640: These include \eb, \ef, \en, \er, \et, \ev, and \e### (# is an octal digit).
                   20641: \ec is equivalent to the \fB\-n\fP option.
                   20642: This expansion may be inhibitted with the \fB\-r\fP option,
                   20643: and may be re-enabled with the addition of the \fB\-e\fP option.
                   20644: .IP "read [\fB\-ru\fIn\fR] \fIname ...\fP"
                   20645: The first variable name may be of the form \fIname\fB?\fIprompt\fR.
                   20646: .IP "readonly [\fIname ...\fP]"
                   20647: .IP "return [\fIstatus\fP]"
                   20648: .ta 5n 10n 30n
                   20649: .de O
                   20650: .br
                   20651: \t\\$1\t\\$2\t\\$3
                   20652: ..
                   20653: .IP "set [\fB\(+-\fP\fI[a-z]\fP] [\fB\(+-o\fP \fIkeyword\fP] ..."
                   20654: Set (\fB\-\fP) or clear (\fB+\fP) a shell option:
                   20655: .O \-a allexport "all new variable are created with export attribute"
                   20656: .O \-e errexit "exit on non-zero status [incorrect]"
                   20657: .O "" bgnice "background jobs are run with lower priority"
                   20658: .if \n(OE \{
                   20659: .O "" emacs "BRL emacs-like line editing"\}
                   20660: .O "" ignoreeof "shell will not exit of EOF, must use \fIexit\fP"
                   20661: .O \-k keyword "variable assignments are recognized anywhere in command"
                   20662: .O "" markdirs "[not implemented]"
                   20663: .O \-m monitor "job control enabled (default for interactive shell)"
                   20664: .O \-n noexec "compile input but do not execute (ignored if interactive)"
                   20665: .O \-f noglob "don't expand filenames"
                   20666: .O \-u nounset "dollar expansion of unset variables is an error"
                   20667: .O \-v verbose "echo shell commands on stdout when compiling"
                   20668: .O \-h trackall "add command pathnames to hash table"
                   20669: .O "" vi "VI-like line editing"
                   20670: .O \-x xtrace "echo simple commands while executing"
                   20671: .IP "set [\fB\-\-\fP] \fIarg ...\fP"
                   20672: Set shell arguments.
                   20673: .IP "shift [\fInumber\fP]"
                   20674: .IP "test"
                   20675: See the attached manual page.
                   20676: .IP "times"
                   20677: .IP "trap [\fIhandler\fP] [\fIsignal ...\fP]"
                   20678: .IP "typeset [\fB\(+-irtx\fP] [\fIname\fP[\fB=\fIvalue\fR] ...]"
                   20679: If no arguments are given, lists all variables and their attributes.
                   20680: .PP
                   20681: If options but no names are given, lists variables with specified
                   20682: attributes, and their values if unless ``+'' is used.
                   20683: .PP
                   20684: If names are given, set the attributes of the named variables.
                   20685: Variables may also be assigned a value.
                   20686: If used inside a function, the created variable are local to the function.
                   20687: .PP
                   20688: The attributes are as follows.
                   20689: .ta 5n 10n
                   20690: \t\-i\tThe variable's value is stored as an integer.
                   20691: .br
                   20692: \t\-x\tThe variable is exported to the enviroment.
                   20693: .br
                   20694: \t\-r\tThe variable is read-only cannot be reassigned a value.
                   20695: .br
                   20696: \t\-t\tTrace (not implemented).
                   20697: .br
                   20698: \t\-f\tList functions instead of variable.
                   20699: .\".IP "ulimit [\fB\-f\fP] [\fIvalue\fP]"
                   20700: .ds OZ <OZ>
                   20701: .IP "\fBulimit\fP \*(OK \fB\-\*(OZ\fP \*(CK \*(OK \fIn\fP \*(CK"
                   20702: .RS
                   20703: .TP "\w'\fB\-\-\ \ \ 'u"
                   20704: .if \n(OB \{.B \-c
                   20705: Impose a size limit of
                   20706: .I n\^
                   20707: blocks on the size of core dumps.
                   20708: .TP
                   20709: .B \-d
                   20710: Impose a size limit of
                   20711: .I n\^
                   20712: blocks on the size of the data area.\}
                   20713: .TP
                   20714: .B \-f
                   20715: Impose a size limit of
                   20716: .I n
                   20717: blocks on files written by the shell
                   20718: and its child processes (files of any size may be read).
                   20719: .if \n(OB \{.TP
                   20720: .B \-m
                   20721: Impose a soft limit of
                   20722: .I n\^
                   20723: blocks on the size of physical memory.
                   20724: .TP
                   20725: .B \-t
                   20726: Impose a time limit of
                   20727: .I n\^
                   20728: seconds to be used by each process.\}
                   20729: .PP
                   20730: If no option is given,
                   20731: .B \-f
                   20732: is assumed.
                   20733: If
                   20734: .I n
                   20735: is omitted, the current limit is printed.
                   20736: As far as
                   20737: .B ulimit
                   20738: is concerned, a ``block'' is 512 bytes.
                   20739: .PP
                   20740: You may lower your own resource limit,
                   20741: but only a super-user (see
                   20742: .IR su (1M))
                   20743: can raise a limit.
                   20744: .RE
                   20745: .IP "umask [\fIvalue\fP]"
                   20746: .IP "unalias \fIname ...\fP"
                   20747: The aliases for the given names are removed.
                   20748: .IP "unset [\fB\-f\fP] \fIname ...\fP"
                   20749: .IP "wait [\fIprocess-id\fP]"
                   20750: .IP "whence [\fB\-v\fP] name ..."
                   20751: For each name, the type of command is listed.
                   20752: The \fB\-v\fP flag causes function and alias values to be listed.
                   20753: .SS Job Control
                   20754: Job control features are enabled by the
                   20755: \fB\-m\fP or \fB\-o monitor\fP flags.
                   20756: When job control is enabled, and the system supports job control,
                   20757: background commands and foreground commands that have been stopped
                   20758: (usually by a
                   20759: .SM SIGTSTP
                   20760: signal generated by typing
                   20761: .IR ^Z\^ )
                   20762: are placed into separate individual
                   20763: .IR "process groups" .
                   20764: The following commands are used to manipulate these process groups:
                   20765: .PP
                   20766: .PD 0
                   20767: .TP "\w'\fBkill\fP \*(OK \fIjob\fP \*(CK\ \ \ 'u"
                   20768: \fBjobs\fP
                   20769: Display information about the controlled jobs.
                   20770: The job number is given preceeded by a percent sign,
                   20771: followed by a plus sign if it is the ``current job'',
                   20772: or by a minus sign if it is the ``previous job'',
                   20773: then the process group number for the job,
                   20774: then the command.
                   20775: .TP
                   20776: \fBkill\fP [\fB\-\fIsignal\fR] \fIjob\fP ...
                   20777: Send a signal (TERM by default) to the named job process group.
                   20778: .TP
                   20779: \fBfg\fP \*(OK \fIjob\fP \*(CK
                   20780: Resume the stopped foreground job in the foreground.
                   20781: If the process group
                   20782: .I n
                   20783: is not specified then the ``current job'' is resumed.
                   20784: .TP
                   20785: \fBbg\fP \*(OK \fIjob\fP \*(CK
                   20786: Resume the stopped foreground job in the background.
                   20787: If the process group
                   20788: .I n
                   20789: is not specified then the ``current job'' is resumed.
                   20790: .PD
                   20791: .PP
                   20792: The \fBfg\fP, \fBbg\fP, \fBkill\fP, and \fBwait\fP commands
                   20793: may refer to jobs with the following ``percent'' sequences.
                   20794: The percent sign is optional with the fg and bg commands.
                   20795: .PP
                   20796: .PD 0
                   20797: .TP "\w'\fBbg\fP \*(OK \fIn\fP \*(CK\ \ \ 'u"
                   20798: .BR %+ ( %\- )
                   20799: If there is a ``current job'' (``previous job''),
                   20800: then that job is selected.
                   20801: .TP
                   20802: .BI % n
                   20803: If the specified job number is one of the known jobs,
                   20804: then that job is selected.
                   20805: .TP
                   20806: .BI % string
                   20807: If the string matches the initial part of a job's command,
                   20808: then that job is selected.
                   20809: .TP
                   20810: .BI %? string
                   20811: As above, but the string may match any portion of the command.
                   20812: .sp
                   20813: .PP
                   20814: If the system does not support job control, monitor mode enables
                   20815: job reporting.  The jobs and kill commands
                   20816: functions as above, and you will
                   20817: be informed when background jobs complete.  Fg and bg are not 
                   20818: availiable.
                   20819: .PD
                   20820: .br
                   20821: .SS "Interactive Input Line Editing"
                   20822: When the
                   20823: .B emacs
                   20824: option is set,
                   20825: interactive input line editing is enabled.
                   20826: This mode is slightly different from the emacs mode in AT&T's KornShell.
                   20827: In this mode various
                   20828: .I "editing commands"
                   20829: (typically bound to one or more control characters)
                   20830: cause immediate actions without waiting for a new-line.
                   20831: Several
                   20832: .I "editing commands"
                   20833: are bound to particular control characters
                   20834: when the shell is invoked;
                   20835: these bindings can be changed using the following commands:
                   20836: .br
                   20837: .PP
                   20838: .PD 0
                   20839: .TP 2i
                   20840: \fBbind\fP
                   20841: The current bindings are listed.
                   20842: .TP
                   20843: \fBbind\fP \*(OK \fIstring\fP \*(CK = \*(OK \fIediting-command\fP \*(CK
                   20844: The specified
                   20845: .I "editing command\^"
                   20846: is bound to the given
                   20847: .IR string ,
                   20848: which should consist of a control character
                   20849: (which may be written using ``caret notation'' \fB^\fP\fIx\fP\|),
                   20850: optionally preceded by one of the two prefix characters.
                   20851: Future input of the
                   20852: .I string
                   20853: will cause the
                   20854: .I "editing command\^"
                   20855: to be immediately invoked.
                   20856: .br
                   20857: Note that although only two prefix characters (normal ESC and ^X)
                   20858: are supported, some multi-character sequences can be supported:
                   20859: .br
                   20860: bind '^[['=prefix-2
                   20861: .br
                   20862: bind '^XA'=up-history
                   20863: .br
                   20864: bind '^XB'=down-history
                   20865: .br
                   20866: bind '^XC'=forward-char
                   20867: .br
                   20868: bind '^XD'=backward-char
                   20869: .br
                   20870: will bind the arrow keys on an ANSI terminal, or xterm.  Of course some escape
                   20871: sequences won't work out quite that nicely.
                   20872: .TP
                   20873: \fBbind -m\fP \*(OK \fIstring\fP \*(CK = \*(OK \fIsubstitute\fP \*(CK
                   20874: The specified input
                   20875: .I string
                   20876: will afterwards be immediately replaced by the given
                   20877: .I substitute
                   20878: string,
                   20879: which may contain
                   20880: .IR "editing commands" .
                   20881: .PD
                   20882: .PP
                   20883: The following
                   20884: .I "editing commands"
                   20885: are available;
                   20886: first the command name is given
                   20887: followed by its default binding (if any)
                   20888: using caret notation
                   20889: (note that the ASCII
                   20890: .SM ESC
                   20891: character is written as \s-1^[\s0\|),
                   20892: then the editing function performed is decribed.
                   20893: Note that
                   20894: .I "editing command"
                   20895: names are used only with the
                   20896: .B bind
                   20897: command.
                   20898: Furthermore,
                   20899: many
                   20900: .I "editing commands"
                   20901: are useful only on terminals with a visible cursor.
                   20902: The default bindings were chosen to resemble corresponding EMACS key bindings.
                   20903: The users tty characters (eg. erase) are bound to reasonable
                   20904: substitutes.
                   20905: .br
                   20906: .PP
                   20907: .PD 0
                   20908: .TP "\w'\fBdelete-word-backward\ \ ^[\|ERASE\fP\ \ \ 'u"
                   20909: \fBabort\ \ ^G\fP
                   20910: Useful as a response to a request for a
                   20911: .B search-history
                   20912: pattern in order to abort the search.
                   20913: .br
                   20914: .TP
                   20915: \fBauto-insert\fP
                   20916: Simply causes the character to appear as literal input.
                   20917: (Most ordinary characters are bound to this.)
                   20918: .br
                   20919: .TP
                   20920: \fBbackward-char\ \ ^B\fP
                   20921: Moves the cursor backward one character.
                   20922: .br
                   20923: .TP
                   20924: \fBbackward-word\ \ ^[\|b\fP
                   20925: Moves the cursor backward to the beginning of a word.
                   20926: .br
                   20927: .TP
                   20928: \fBbeginning-of-line\ \ ^A\fP
                   20929: Moves the cursor to the beginning of the input line
                   20930: (after the prompt string).
                   20931: .br
                   20932: .TP
                   20933: \fBcomplete\ \ ^[\|^[\fP
                   20934: Automatically completes as much as is unique of the hashed command name
                   20935: or the file name containing the cursor.
                   20936: If the entire remaining command or file name is unique
                   20937: a space is printed after its completion,
                   20938: unless it is a directory name in which case
                   20939: .B /
                   20940: is postpended.
                   20941: If there is no hashed command or file name with the current partial word
                   20942: as its prefix,
                   20943: a bell character is output (usually causing a ``beep'').
                   20944: .br
                   20945: .TP
                   20946: \fBcomplete-command\ \ ^X^[\fP
                   20947: Automatically completes as much as is unique of the hashed command name
                   20948: having the partial word up to the cursor as its prefix,
                   20949: as in the
                   20950: .B complete
                   20951: command described above.
                   20952: Only command and function names seen since the last
                   20953: .B "hash \-r"
                   20954: command are available for completion;
                   20955: the
                   20956: .B "hash"
                   20957: command may be used to register additional names.
                   20958: .br
                   20959: .TP
                   20960: \fBcomplete-file\ \ ^[\|^X\fP
                   20961: Automatically completes as much as is unique of the file name
                   20962: having the partial word up to the cursor as its prefix,
                   20963: as in the
                   20964: .B complete
                   20965: command described above.
                   20966: .br
                   20967: .TP
                   20968: \fBcopy-last-arg\ \ ^[\|_\fP
                   20969: The last word of the previous command is inserted at the
                   20970: cursor.  Note I/O redirections do not count as words of
                   20971: the command.
                   20972: .br
                   20973: .TP
                   20974: \fBdelete-char-backward\ \ ERASE\fP
                   20975: Deletes the character before the cursor.
                   20976: .br
                   20977: .TP
                   20978: \fBdelete-char-forward\fP
                   20979: Deletes the character after the cursor.
                   20980: .br
                   20981: .TP
                   20982: \fBdelete-word-backward\ \ ^[\|ERASE\fP
                   20983: Deletes characters before the cursor back to the beginning of a word.
                   20984: .br
                   20985: .TP
                   20986: \fBdelete-word-forward\ \ ^[\|d\fP
                   20987: Deletes characters after the cursor up to the end of a word.
                   20988: .br
                   20989: .TP
                   20990: \fBdown-history\ \ ^N\fP
                   20991: Scrolls the history buffer forward one line (later).
                   20992: Each input line originally starts just after
                   20993: the last entry in the history buffer,
                   20994: so
                   20995: .B down-history
                   20996: is not useful until either
                   20997: .B search-history
                   20998: or
                   20999: .B up-history
                   21000: has been performed.
                   21001: .br
                   21002: .TP
                   21003: \fBend-of-line\ \ ^E\fP
                   21004: Moves the cursor to the end of the input line.
                   21005: .br
                   21006: .TP
                   21007: \fBeot\ \ ^_\fP
                   21008: Acts as an end-of-file;
                   21009: this is useful because edit-mode input
                   21010: disables normal terminal input canonicalization.
                   21011: .br
                   21012: .TP
                   21013: \fBeot-or-delete\ \ ^D\fP
                   21014: Acts as eot if alone on a line;
                   21015: otherwise acts as delete-char-forward.
                   21016: .br
                   21017: .TP
                   21018: \fBexchange-point-and-mark\ \ ^X\|^X\fP
                   21019: Places the cursor where the mark is, and sets the
                   21020: mark to where the cursor was.
                   21021: .br
                   21022: .TP
                   21023: \fBforward-char\ \ ^F\fP
                   21024: Moves the cursor forward one position.
                   21025: .br
                   21026: .TP
                   21027: \fBforward-word\ \ ^[\|f\fP
                   21028: Moves the cursor forward to the end of a word.
                   21029: .br
                   21030: .TP
                   21031: \fBkill-line\ \ KILL\fP
                   21032: Deletes the entire input line.
                   21033: .br
                   21034: .TP
                   21035: \fBkill-to-eol\ \ ^K\fP
                   21036: Deletes the input from the cursor to the end of the line.
                   21037: .br
                   21038: .TP
                   21039: \fBkill-region\ \ ^W\fP
                   21040: Deletes the input between the cursor and the mark.
                   21041: .br
                   21042: .TP
                   21043: \fBlist\ \ ^[\|?\fP
                   21044: Prints a sorted, columnated list of hashed command names or file names
                   21045: (if any) that can complete the partial word containing the cursor.
                   21046: Directory names have
                   21047: .B /
                   21048: postpended to them,
                   21049: and executable file names are followed by
                   21050: .BR \(** .
                   21051: .br
                   21052: .TP
                   21053: \fBlist-command\ \ ^X\|?\fP
                   21054: Prints a sorted, columnated list of hashed command names
                   21055: (if any) that can complete the partial word containing the cursor.
                   21056: .br
                   21057: .TP
                   21058: \fBlist-file\fP
                   21059: Prints a sorted, columnated list of file names
                   21060: (if any) that can complete the partial word containing the cursor.
                   21061: File type indicators are postpended as described under
                   21062: .B list
                   21063: above.
                   21064: .br
                   21065: .TP
                   21066: \fBnewline\ \ ^J\ \fP\fIand\^\fP\fB\ ^M\fP
                   21067: Causes the current input line to be processed by the shell.
                   21068: (The current cursor position may be anywhere on the line.)
                   21069: .br
                   21070: .TP
                   21071: \fBnewline-and-next\ \ ^O\fP
                   21072: Causes the current input line to be processed by the shell, and
                   21073: the next line from history becomes the current line.  This is
                   21074: only useful after an up-history or search-history.
                   21075: .br
                   21076: .TP
                   21077: \fBno-op\ \ QUIT\fP
                   21078: Does nothing.
                   21079: .br
                   21080: .TP
                   21081: \fBprefix-1\ \ ^[\fP
                   21082: Introduces a 2-character command sequence.
                   21083: .br
                   21084: .TP
                   21085: \fBprefix-2\ \ ^X\fP
                   21086: Introduces a 2-character command sequence.
                   21087: .br
                   21088: .TP
                   21089: \fBquote\ \ ^^\fP
                   21090: The following character is taken literally
                   21091: rather than as an
                   21092: .IR "editing command" .
                   21093: .br
                   21094: .TP
                   21095: \fBredraw\ \ ^L\fP
                   21096: Reprints the prompt string and the current input line.
                   21097: .br
                   21098: .TP
                   21099: \fBsearch-character\ \ ^]\fP
                   21100: Search forward in the current line for the next keyboard character.
                   21101: .br
                   21102: .TP
                   21103: \fBsearch-history\ \ ^R\fP
                   21104: Enter incremental search mode.
                   21105: The internal history list is searched backwards for commands matching the input.
                   21106: An initial ``^'' in the search string anchors the search.
                   21107: The escape key will leave search mode.
                   21108: Other commands will be executed after leaving search mode (unless
                   21109: of course they are prefixed by escape, in which case they will
                   21110: almost certainly do the wrong thing).
                   21111: Successive
                   21112: .B search-history
                   21113: commands continue searching backward
                   21114: to the next previous occurrence of the pattern.
                   21115: The history buffer retains only a finite number of lines;
                   21116: the oldest are discarded as necessary.
                   21117: .br
                   21118: .TP
                   21119: \fBset-mark-command\ \ ^]\|<space>\fP
                   21120: Search forward in the current line for the next keyboard character.
                   21121: .br
                   21122: .ie \n(OX \{.TP
                   21123: \fBstuff\ \ ^T\fP\}
                   21124: .el \{.TP
                   21125: \fBstuff\fP\}
                   21126: On systems supporting it,
                   21127: pushes the bound character back onto the terminal input
                   21128: where it may receive special processing by the terminal handler.
                   21129: .if \n(OX \{This is useful for the BRL
                   21130: .B ^T
                   21131: ``mini-systat'' feature,
                   21132: for example.\}
                   21133: .br
                   21134: .TP
                   21135: \fBstuff-reset\fP
                   21136: Acts like
                   21137: .BR stuff\^ ,
                   21138: then aborts input the same as an interrupt.
                   21139: .br
                   21140: .ie \n(OX \{.TP
                   21141: \fBtranspose-chars\fP\}
                   21142: .el \{.TP
                   21143: \fBtranspose-chars\ \ ^T\fP\}
                   21144: Exchanges the two characters on either side of the cursor, or
                   21145: the two previous characters if the cursor is at end of line.
                   21146: .br
                   21147: .TP
                   21148: \fBup-history\ \ ^P\fP
                   21149: Scrolls the history buffer backward one line (earlier).
                   21150: .br
                   21151: .TP
                   21152: \fByank\ \ ^Y\fP
                   21153: Inserts the most recently killed text string at the current cursor position.
                   21154: .br
                   21155: .TP
                   21156: \fByank-pop\ \ ^[\|y\fP
                   21157: Immediately after a
                   21158: .BR yank ,
                   21159: replaces the inserted text string with the
                   21160: next previous killed text string.
                   21161: .PD
                   21162: .br
                   21163: .SH FILES
                   21164: ~/.profile
                   21165: .br
                   21166: /etc/profile
                   21167: .SH SEE ALSO
                   21168: Sh(1) on System V or Sun OS.
                   21169: .LP
                   21170: .I "UNIX Shell Programming,"
                   21171: Stephan G. Kochan,
                   21172: Patrick H. Wood,
                   21173: Hayden.
                   21174: .LP
                   21175: .I "KornShell: Command and Programming Language (not yet published),"
                   21176: Morris Bolsky and David Korn.
                   21177: .SH AUTHORS
                   21178: Based on the public domain 7th edition Bourne shell.
                   21179: .LP
                   21180: System V and Korn modifications by Eric Gisin,
                   21181: with contributions by
                   21182: Ron Natalie, Arnold Robbins, Doug Gwyn, Erik Baalbergen, AT&T (getopt(3)),
                   21183: John McMillan, Simon Gerraty and Peter Collinson.
                   21184: .SH DIFFERENCES FROM AT&T VERSION
                   21185: Csh-style alternations are implemented.
                   21186: Variable arrays are not implemented.
                   21187: Variable attributes other than integer are not implemented.
                   21188: The \fBERR\fP and \fBEXIT\fP traps are not implemented for functions.
                   21189: Alias expansion is inhibited at the beginning of an alias definition
                   21190: in the AT&T version.
                   21191: Korn evaluates expressions differently [elaborate].
                   21192: .SH BUGS
                   21193: Interactive shells may occasionally hang while waiting for a job
                   21194: in the BSD version.
                   21195: .LP
                   21196: The 8th bit is stripped in emacs mode.
                   21197: .LP
                   21198: Quoting double-quote (") characters inside back-quote (`) inside
                   21199: double-quotes does not behave properly.  Why are you doing this?
                   21200: .LP
                   21201: The emacs mode can ``lose'' stty command done by the user.
                   21202: .LP
                   21203: Unsetting special variables
                   21204: may cause unexpected results.
                   21205: .LP
                   21206: Functions declared as having local scope really have global scope.
                   21207: .LP
                   21208: Here documents inside functions do not work correctly.
                   21209: .LP
                   21210: Exit on error (\fBset \-e\fP or \fBset -o errexit\fP) does not work
                   21211: correctly.
                   21212: .TH TEST 1 "January 1988" "Korn shell"
                   21213: .ta 30n
                   21214: .de X
                   21215: .br
                   21216: \\$1\t\\$2
                   21217: ..
                   21218: .SH NAME
                   21219: test \- test condition (Korn and 8th edition)
                   21220: .SH SYNOPSIS
                   21221: \fBtest\fP \fIexpression\fP
                   21222: .br
                   21223: \fB[\fP \fIexpression\fP \fB]\fP
                   21224: .SH DESCRIPTION
                   21225: \fBTest\f evalutates the \fIexpression\fP and returns zero status if true,
                   21226: and non-zero status otherwise.
                   21227: It is normally used as the controlling command of the \fBif\fP and \fBwhile\fP statements.
                   21228: .LP
                   21229: The following basic expressions are available.
                   21230: .IP
                   21231: .X "-r file" "file exists and is readable"
                   21232: .X "-w file" "file exists and is writable"
                   21233: .X "-x file" "file exists and is executable"
                   21234: .X "-f file" "file is a regular file"
                   21235: .X "-d file" "file is a directory"
                   21236: .X "-c file" "file is a character special device"
                   21237: .X "-b file" "file is a block special device"
                   21238: .X "-p file" "file is a named pipe"
                   21239: .X "-u file" "file mode has setuid bit"
                   21240: .X "-g file" "file mode has setgid bit"
                   21241: .X "-k file" "file mode has sticky bit"
                   21242: .X "-s file" "file is not empty"
                   21243: .X "-L file" "file is a symbolic link"
                   21244: .X "-S file" "file is a socket"
                   21245: .X "file -nt file" "first file is newer than second file"
                   21246: .X "file -ot file" "first file is older than second file"
                   21247: .X "file -ef file" "first file is the same file as second file"
                   21248: .X "-t filedes" "file descriptor is a tty device"
                   21249: .IP
                   21250: .X "string" "string is not null"
                   21251: .X "-z string" "string is null"
                   21252: .X "-n string" "string is not null"
                   21253: .X "string = string" "strings are equal"
                   21254: .X "string != string" "strings are not equal"
                   21255: .IP
                   21256: .X "number -eq number" "numbers compare equal"
                   21257: .X "number -ne number" "numbers compare not equal"
                   21258: .X "number -ge number" "numbers compare greater than or equal"
                   21259: .X "number -gt number" "numbers compare greater than"
                   21260: .X "number -le number" "numbers compare less than or equal"
                   21261: .X "number -lt number" "numbers compare less than"
                   21262: .LP
                   21263: The above basic expressions may be combined with the following operators.
                   21264: .IP
                   21265: .X "expr -o expr" "logical or"
                   21266: .X "expr -a expr" "logical and"
                   21267: .X "! expr" "logical not"
                   21268: .X "( expr )" "grouping"
                   21269: .SH AUTHOR
                   21270: Erik Baalbergen. Modified by Arnold Robbins.
                   21271: .rn LP P
                   21272: .TH GETOPTS 1 "January 1988" "Korn shell"
                   21273: .SH NAME
                   21274: getopts \- parse command options
                   21275: .SH SYNOPSIS
                   21276: .B getopts
                   21277: optstring name [arg ...]
                   21278: .SH DESCRIPTION
                   21279: .I getopts
                   21280: is used by shell procedures
                   21281: to parse positional parameters and to check for legal options.
                   21282: It supports all applicable rules of the command syntax standard
                   21283: (see Rules 3-10,
                   21284: .IR intro (1)).
                   21285: It should be used in place of the
                   21286: .IR getopt (1)
                   21287: command.
                   21288: (See the
                   21289: .BR \s-1WARNING\s0 ,
                   21290: below.)
                   21291: .PP
                   21292: .I optstring
                   21293: must contain the option letters the command using
                   21294: .I getopts
                   21295: will recognize;
                   21296: if a letter is followed by a colon,
                   21297: the option is expected to have an argument
                   21298: which should be separated from it by white space.
                   21299: .PP
                   21300: Each time it is invoked,
                   21301: .I getopts
                   21302: will place the next option in the shell variable
                   21303: .I name
                   21304: and the index of the next argument to be processed in the shell variable
                   21305: .BR \s-1OPTIND\s0 .
                   21306: Whenever the shell or a shell procedure is invoked,
                   21307: .B \s-1OPTIND\s0
                   21308: is initialized to
                   21309: .BR 1 .
                   21310: .PP
                   21311: When an option requires an option-argument,
                   21312: .I getopts
                   21313: places it in the shell variable
                   21314: .BR \s-1OPTARG\s0 .
                   21315: .P
                   21316: If an illegal option is encountered,
                   21317: .B ?\&
                   21318: will be placed in
                   21319: .IR name .
                   21320: .P
                   21321: When the end of the options is encountered,
                   21322: .I getopts
                   21323: exits with a non-zero exit status.
                   21324: The special option
                   21325: .RB `` \-\- ''
                   21326: may be used to delimit the end of the options.
                   21327: .P
                   21328: By default,
                   21329: .I getopts
                   21330: parses the positional parameters.
                   21331: If extra arguments
                   21332: .RI ( arg
                   21333: \&...) are given on the
                   21334: .I getopts
                   21335: command line,
                   21336: .I getopts
                   21337: will parse them instead.
                   21338: .PP
                   21339: So all new commands will adhere to the command syntax standard described in
                   21340: .IR intro (1),
                   21341: they should use
                   21342: .IR getopts (1)
                   21343: or
                   21344: .IR getopt (3C)
                   21345: to parse positional parameters
                   21346: and check for options that are legal for that command
                   21347: (see
                   21348: .BR \s-1WARNINGS\s0 ,
                   21349: below).
                   21350: .SH EXAMPLE
                   21351: The following fragment of a shell program
                   21352: shows how one might process the arguments
                   21353: for a command that can take the options
                   21354: .B a
                   21355: or
                   21356: .BR b ,
                   21357: as well as the option
                   21358: .BR o ,
                   21359: which requires an option-argument:
                   21360: .PP
                   21361: .RS
                   21362: .nf
                   21363: .ss 18
                   21364: .ta +.5i +1i
                   21365: \fBwhile getopts abo: c
                   21366: do
                   21367:        case $c in
                   21368:        a\(bvb) FLAGS=$FLAGS$c;;
                   21369:        o)      OARG=$OPTARG;;
                   21370:        \e?)    echo $USAGE 1>&2
                   21371:                exit 2;;
                   21372:        esac
                   21373: done
                   21374: shift OPTIND\-1\fP
                   21375: .fi
                   21376: .ta
                   21377: .ss 12
                   21378: .RE
                   21379: .PP
                   21380: This code will accept any of the following as equivalent:
                   21381: .PP
                   21382: .RS
                   21383: .nf
                   21384: .ss 18
                   21385: \fBcmd \-a \-b \-o "xxx z yy" file
                   21386: cmd \-a \-b \-o "xxx z yy" \-\- file
                   21387: cmd \-ab \-o "xxx z yy" file
                   21388: cmd \-ab \-o "xxx z yy" \-\- file\fP
                   21389: .fi
                   21390: .ss 12
                   21391: .RE
                   21392: .SH SEE ALSO
                   21393: intro(1),
                   21394: sh(1).
                   21395: .br
                   21396: getopt(3C)
                   21397: in the
                   21398: .IR "Programmer's Reference Manual" .
                   21399: .br
                   21400: .IR "UNIX System V Release 3.0 Release Notes" .
                   21401: .SH WARNING
                   21402: Although the following command syntax rule (see
                   21403: .IR intro (1))
                   21404: relaxations are permitted under the current implementation,
                   21405: they should not be used because they may not be supported
                   21406: in future releases of the system.
                   21407: As in the
                   21408: .B \s-1EXAMPLE\s0
                   21409: section above,
                   21410: .B a
                   21411: and
                   21412: .B b
                   21413: are options,
                   21414: and the option
                   21415: .B o
                   21416: requires an option-argument:
                   21417: .PP
                   21418: .RS
                   21419: .nf
                   21420: .ta +1i +1.5i
                   21421: \fBcmd \-aboxxx file\fP        (Rule 5 violation: options with
                   21422:        option-arguments must not be grouped with other options)
                   21423: \fBcmd \-ab \-oxxx file\fP     (Rule 6 violation: there must be
                   21424:        white space after an option that takes an option-argument)
                   21425: .fi
                   21426: .ta
                   21427: .RE
                   21428: .PP
                   21429: Changing the value of the shell variable
                   21430: .B \s-1OPTIND\s0
                   21431: or parsing different sets of arguments
                   21432: may lead to unexpected results.
                   21433: .SH DIAGNOSTICS
                   21434: .I getopts
                   21435: prints an error message on the standard error output
                   21436: when it encounters an option letter not included in
                   21437: .IR optstring .
                   21438: ./pdksh/INSTALL   644    653   1762       11466  5243743523  10471 0ustar  hluBUILDING THE PD KSH
                   21439: ===================
                   21440: 
                   21441: The PD KSH can be built in two ways.  The default method uses
                   21442: the POSIX/ANSI compatability libraries in ./std.  The
                   21443: alternative method is to build the ksh in ./sh without the ./std
                   21444: tree.  The second method should be used only if a) you have a
                   21445: real POSIX environemnt or b) you have major difficulties with
                   21446: building the ./std tree.
                   21447: 
                   21448: I have modified the source slightly to make standalone building
                   21449: simpler.  Using -DNOSTDHDRS avoids attempts to include ANSI
                   21450: headers that may be lacking.  I have built the shell this way on
                   21451: all Sun platforms and on a Bull DPX/2 (which has good POSIX
                   21452: support).  The config file defines USE_SIGACT so that the shell
                   21453: will use the XPG3 signalaction() and friends.  You should leave
                   21454: USE_SIGACT defined, sh/sigact.c contains an implementation for
                   21455: systems that lack this facility. 
                   21456: 
                   21457: It is recommended that you try using the ./std tree first.  This
                   21458: avoids problems like BSD times() calls that do not return an
                   21459: indication of elapsed time and so on.
                   21460: 
                   21461: Using ./std:
                   21462: ------------
                   21463: 
                   21464: If you are on a Sun building it quite simple:
                   21465: 
                   21466:        make CONFIG=-D_BSD
                   21467: 
                   21468: will do it.  If you have a sun386 or sun3 and have gcc, it is
                   21469: worth using, just add CC="gcc -pipe" to the above command line.
                   21470: If you have SunOS 4.1 or later you probably need to add
                   21471: -DHAVE_SYS_STDTYPES
                   21472: 
                   21473: Building on other systems may well be more difficult.
                   21474: Apparently the creating of the ./std/h tree causes problems on
                   21475: some systems.  
                   21476: 
                   21477: 
                   21478: Notes on ./std:
                   21479: ---------------
                   21480: 
                   21481: I have updated the Makefiles in ./std/stdc and ./tsd/posix to
                   21482: maintain the objects within the libraries.  Ie.
                   21483: libstdc.a(strstr.o) If your make(1) doesn't know how to do this
                   21484: then you will need to modify the makefiles accordingly.
                   21485: 
                   21486: In ReadMe.jrm, John MacMillan recommends being cautious of
                   21487: std/libstdc.a and using only those routines which your system
                   21488: lacks.  Please note that I have tested virtually none of
                   21489: ./std/stdc.  The Makefile contains target lines for most modules
                   21490: but most are commented out.  I suggest you uncomment _only_
                   21491: those that you need.
                   21492: 
                   21493: On the other hand std/libposix.a seems quite safe, and
                   21494: indeed provides a better times() call for BSD systems.
                   21495: 
                   21496: Read ReadMe.jrm for more...
                   21497: 
                   21498: 
                   21499: Building without ./std:
                   21500: -----------------------
                   21501: 
                   21502: On some systems it might be worth forgetting about ./std/lib*
                   21503: either because they proved too difficult to build or they seem
                   21504: unnecessary.  As previously indicated I have done this on Sun's
                   21505: and on a Bull system.  On Sun's it is perhaps not a great idea
                   21506: as you then get the system's times() call which does not behave
                   21507: the way the shell wants.
                   21508: 
                   21509: In anycase to build without ./std, you simply cd to ./sh and
                   21510: either edit the Makefile accordingly, or use an appropriate
                   21511: command line.  For instance:
                   21512: 
                   21513: Sun with SunOS 4.0:
                   21514: 
                   21515:        cd ./sh
                   21516:        ln -s ../std/stdc/strstr.c .
                   21517:        ln -s ../std/stdc/memmove.c .
                   21518:        make CFLAGS="-D_BSD -DNOSTDHDRS" \
                   21519:                XOBJS="strstr.o memmove.o" LDLIBS="" LDFLAGS=""
                   21520: 
                   21521: Note that we still need a couple of functions from ./std/stdc
                   21522: 
                   21523: On the Bull system which is a POSIX compliant System V machine:
                   21524: 
                   21525:        cd ./sh
                   21526:        make CFLAGS="-D_SYSV" LDLIBS="-lc_s" LDFLAGS=""
                   21527:        make CC=gcc CFLAGS="-D_POSIX_SOURCE" LDLIBS="-lc_s" LDFLAGS=""
                   21528: 
                   21529: INSTALLING:
                   21530: ===========
                   21531: 
                   21532: This is quite simple.  
                   21533: 
                   21534:        # cp ./ksh /bin
                   21535:        # chmod 555 /bin/ksh
                   21536: 
                   21537: The above assumes of course that you don't already have a
                   21538: /bin/ksh :-)
                   21539: The manual page ksh.1 should be copied to an appropriate
                   21540: location.
                   21541: BSD:
                   21542:        # cp ksh.1 /usr/man/man1
                   21543: SYSV:
                   21544:        # nroff -man ksh.1 > /usr/catman/u_man/man1/ksh.1
                   21545:        # pack /usr/catman/u_man/man1/ksh.1
                   21546: 
                   21547: Or something similar.  For systems such as Sun's that really
                   21548: only ship with a C-shell environment, the ./etc directory
                   21549: contains a useful /etc/profile and /etc/ksh.kshrc file to
                   21550: provide a suitable environemnt for /bin/sh and /bin/ksh users,
                   21551: they should work, they are straight of my system and I use them
                   21552: on Sun,Bull and even an SCO system.
                   21553: 
                   21554: 
                   21555: PROBLEMS:
                   21556: =========
                   21557: 
                   21558: Clearly building will not be so simple on all systems.
                   21559: Apparently some of the enum manipulations border on ilegal and
                   21560: cause some compilers problems.  Curiously both gcc -ansi and the
                   21561: GreenHills compiler on the Bull system are quite picky and did
                   21562: not complain.  Note if you want to use gcc -ansi you may well
                   21563: need to add some definitions, for instance the following all
                   21564: work on the sun386:
                   21565: 
                   21566:        CC=cc
                   21567:        CC=gcc
                   21568:        CC=gcc -ansi -Dsun -Di386 -Dsun386
                   21569: 
                   21570: The last three items on the last line are normally all defined
                   21571: automatically, but this is disabled when -ansi is used.  The
                   21572: system headers do not work unless they know what architecture is
                   21573: in use.  
                   21574: 
                   21575: On the Bull DPX/2 I used gcc-2.1, my gcc port will be available
                   21576: as of release 2.2.  To save effort I found it necessary to copy
                   21577: stdio.h and stdlib.h to gcc's private include directory and edit
                   21578: them to remove unnecessary #ifdef's and unwanted #include's.
                   21579: 
                   21580: If you find and fix a problem please fill in a copy of
                   21581: ./bug-report and e-mail it to [email protected]
                   21582: 
                   21583: Enjoy!
                   21584: 
                   21585: Simon J. Gerraty <[email protected]>
                   21586: 
                   21587: ./pdksh/Changes.mlj   644    653   1762        3361  5243742730  11466 0ustar  hluI got the pd-ksh from John MacMillan after he indicated that he
                   21588: had a version of it that had vi editing (I'd seen various versions
                   21589: with emacs-editing, but none with vi).
                   21590: 
                   21591: It had a few bugs and areas which were not quite complete.  I fixed
                   21592: (or at least tried) to fix several; there are still some things
                   21593: which I plan on doing (or at least looking into).
                   21594: 
                   21595: Bugs fixed (or at least abated):
                   21596: 
                   21597:     vi-mode changes:
                   21598:     - Changed memcpy() to memmove(), which fixed the trashing of
                   21599:       the end of the edit buffer while inserting in the middle
                   21600:       of a line or with use of '#'
                   21601:     - using 'r' replacing the current character with ^@
                   21602:     - typing ctrl-c resulting in next command being garbled
                   21603:     - lack of support for '-' and '+' (pretty trivial)
                   21604:     - finish adding support for '*' (not entirely sure I'm freeing
                   21605:       malloc'ed memory correctly here, but I haven't had any problems)
                   21606:     - treats '_' as end of a word
                   21607: 
                   21608:     general changes:
                   21609:     - reporting "not found" when a file actually doesn't have
                   21610:       the appropriate execute bit set (now says "cannot execute"
                   21611:       or "not found", as appropriate)
                   21612: 
                   21613: 
                   21614: Still to do:
                   21615: 
                   21616:     vi changes:
                   21617:     - fix ctrl-r (I've come up with a hack, but it involves
                   21618:       redrawing the screen a lot when it isn't necessary; I
                   21619:       really wouldn't consider this a fix)
                   21620:     - add support for 'v'
                   21621: 
                   21622:     general changes:
                   21623:     - seems to be a memory leak when executing shells in the
                   21624:       current shell; repeatedly executing ". /etc/profile"
                   21625:       increased the size of the program as reported in the
                   21626:       "SZ" field of "ps -l"
                   21627:     - don't give a file its complete pathname in argv[0]; only
                   21628:       its filename (religious issue?)
                   21629:     - history recall should start at the previous command, not
                   21630:       the current one (typing "r r" causes an infinite loop)
                   21631: ./pdksh/ChangeLog   644    653   1762        2332  5243743644  11166 0ustar  hluSat Aug  1 17:11:24 1992  Simon J. Gerraty  (sjg@zen)
                   21632: 
                   21633:        * Incorporated massive contribution from Peter Collinson
                   21634:        Refer to Changes.pc
                   21635: 
                   21636:        * Incorporated Emacs-style completion provided by
                   21637:        [email protected] this a bit nicer than the standard ksh
                   21638:        file completion.
                   21639: 
                   21640: Sun May  3 17:50:03 1992  Simon J. Gerraty  (sjg@zen)
                   21641: 
                   21642:        * Updated MACHINES.
                   21643:        * Placed source under CVS.  This should help with processing fixes
                   21644:        from the field.
                   21645: 
                   21646: Sat Apr 25 10:53:20 1992  Simon J. Gerraty  (sjg@zen)
                   21647: 
                   21648:        * Getting ready for 4.3 release.  
                   21649: 
                   21650: Fri Nov 22 22:24:29 1991  Simon J. Gerraty  (sjg at zen)
                   21651: 
                   21652:        * Cleaned up the build process slightly.  Makefiles in ./std tree
                   21653:        now maintain objects within the libraries rather than simply
                   21654:        building the .o's and archiving them.  Of course the make(1) used
                   21655:        must know how to maintain libraries :-)
                   21656: 
                   21657:        * Added bug.report as a template for bug reporting.
                   21658: 
                   21659:        * Source in ./sh can be built independently of ./std tree if
                   21660:        desired.  See comments in ./sh/Makefile.
                   21661: 
                   21662:        * As originally distributed some of libstdc.a was not used and
                   21663:        libposix.a was not used at all.  On Sun's this highlighted a bug
                   21664:        (incompatibility) in the times() call.  Now the ./std/libs are
                   21665:        used fully, and the supplied times() call functions as expected.
                   21666: 
                   21667: ./pdksh/MACHINES   644    653   1762        3150  5243743645  10526 0ustar  hluThis file documents some the machines that pdksh has been build
                   21668: on and notes that apply.
                   21669: 
                   21670: Notes:
                   21671: (1)    Built and tested by me (sjg), seems ok :-)
                   21672: (2)    Reported ok (may mean earlier version)
                   21673: (3)    Reported no good
                   21674: (4)    Built with ./std/lib*
                   21675: (5)    Built without ./std/lib*
                   21676: (6)    No job control
                   21677: 
                   21678: If you succesfully build this shell on another system please let
                   21679: me know. 
                   21680: 
                   21681: System, OS                     Notes   Compiler/Flags
                   21682: --------------------------     -----   --------------
                   21683: sun386, SunOS 4.0.2            1,4     {cc,gcc} -D_BSD
                   21684: sun4c, SunOS 4.1.1             1,4     {cc,gcc-2.1} -ansi -D_BSD -DHAVE_SYS_STDTYPES
                   21685: sun3,  SunOS 4.0.3             1,4     {cc,gcc} -D_BSD
                   21686: sun3,  SunOS 4.1.1             1,4     {cc,gcc} -ansi -D_BSD -DHAVE_SYS_STDTYPES
                   21687: Bull DPX/2, B.O.S. 2.00.45     1,5     {cc,gcc-2.1} -ansi -D_POSIX_SOURCE
                   21688: Bull XPS-100                   1,6     cc -D_SYSV -DUSE_SIGNAL
                   21689: i386,  BSDI BSD/386            2
                   21690: 
                   21691: NOTES:
                   21692: The table above sumarizes the config used.  {cc,gcc} indicates
                   21693: either compiler can be used.  If gcc-2.1 rather than gcc is
                   21694: indicated then gcc < 2 may not work.  This is at least true of
                   21695: sun4c (sparc) systems.
                   21696: 
                   21697: Bull DPX/2:
                   21698: 
                   21699: pdksh is not needed on this system.  It is simply used as a
                   21700: System V / POSIX test bed.  Build without ./std tree.  I only
                   21701: tried with gcc-2.1. -D_SYSV must be left out of CFLAGS for POSIX
                   21702: functions such as sigaction() to be used.
                   21703: 
                   21704: Bull XPS-100:  
                   21705: 
                   21706: Be sure to rm std/h/dirent.h std/h/sys/types.h and undef JOBS as
                   21707: the kernel does not support it.  This machine has a sigaction()
                   21708: implementation that appears to be faulty.  A SIGINT terminates
                   21709: the shell, when using the system's sigaction().  Undefining
                   21710: USE_SIGACT does the trick.  sigact.c can now be forced to build
                   21711: by defining USE_SIGNAL, but this is not tested on the XPS.
                   21712: 
                   21713: ./pdksh/ReadMe.jrm   644    653   1762       11527  5243742743  11310 0ustar  hluBUILDING THE PD KSH
                   21714: ===================
                   21715: 
                   21716: As usual, there are differences between BSD and System V
                   21717: versions.  Ideally, all you have to do is edit the Makefile in
                   21718: this directory to set the CONFIG macro to the appropriate value.
                   21719: (Actually, you may wish to change the CONFIG macro in all
                   21720: Makefiles; if you always invoke make(1) from here, CONFIG will
                   21721: be passed down, but if you invoke make(1) from a subdirectory
                   21722: you'll want the appropriate definition in that Makefile.)
                   21723: 
                   21724: Of course it's not quite that simple.  You may, however, take
                   21725: solace in the knowledge that it used to be worse.
                   21726: 
                   21727: The Compatibility Libraries
                   21728: ---------------------------
                   21729: 
                   21730: Eric Gisin wrote this shell using ANSI C and POSIX as
                   21731: portability guidlines.  Realizing that nobody had a POSIX
                   21732: system and almost no one had an ANSI C environment, he provided
                   21733: minimal compatibility libraries.
                   21734: 
                   21735: There are two libraries, one for POSIX (libposix.a) and one for
                   21736: ANSI C (libstdc.a).
                   21737: 
                   21738: Libposix.a is pretty simple.  Nothing in it has ever broken on
                   21739: me, so I'd just leave it.  It provides a version of dup2() for
                   21740: System V systems.
                   21741: 
                   21742: Libstdc.a is a bit hairy.  I recommend looking at the routines
                   21743: provided and, and editing the std/stdc Makefile and only
                   21744: including objects that have routines your system libc.a is
                   21745: lacking.  Various of the provided routines are just plain
                   21746: flaky, but only when they're not really needed.  The other
                   21747: hairy thing he does is craft an ANSI stdio.h from the system
                   21748: supplied one and one of his own.  Again, it's better than it
                   21749: used to be, but it's still a hack, and you may have to modify
                   21750: it by hand.
                   21751: 
                   21752: You will also need a POSIX compatible set of directory reading
                   21753: routines.  System V.3 systems have this in libc.a.  The
                   21754: std/posix directory provides a something for BSD systems.  I
                   21755: use a slightly modified version of Doug Gwyn's PD version.
                   21756: 
                   21757: (The ``slightly modified'' is to work around a bug in Gwyn's version.
                   21758: The POSIX routines are documented as returning failure if the file for
                   21759: opendir(3) is not a directory.  Gwyn attempts to open(2) the file, and
                   21760: then stats it to see if the file is a directory.  However, if the file
                   21761: is a special file, and the open(2) doesn't return, you're screwed.  My
                   21762: change was to open the file with the O_NDELAY flag, but Gwyn didn't
                   21763: feel this was portable (true, but I only do it where it works) and
                   21764: that stat-ing before the open would be too slow (true).  The upshot is
                   21765: if you use his routines unmodified, don't ever do an "ls -l /dev/*/*".)
                   21766: 
                   21767: The Shell Source
                   21768: ----------------
                   21769: 
                   21770: The source for the shell itself is in the sh directory.  There you
                   21771: will want to edit config.h to determine the configuration options.  Vi
                   21772: mode is in kind of rough shape, but does work.  DIRSTACK routines
                   21773: aren't implemented yet, so again, why bother.  SWTCH is a bit arcane,
                   21774: but it you use shl(1) and you define EMACS or VI you want to define
                   21775: this.  JOBS is really only useful on BSD systems.  It might work on
                   21776: systems that have POSIX job control, but I wouldn't bet on it.
                   21777: SHARPBANG is only useful on systems where the exec() family don't
                   21778: honour the #!/prog/path convention.
                   21779: 
                   21780: This is where the shell gets built so you may wish to change
                   21781: the OTHERLIBS macro in the Makefile to point to your POSIX
                   21782: directory routines, or to use -lc_s, or whatever.
                   21783: 
                   21784: Miscellaneous
                   21785: -------------
                   21786: 
                   21787: The Makefiles that actually compile things use the macro
                   21788: CCOPTS, so you can change it in individual Makefiles or specify
                   21789: it on the command line, eg. "make CCOPTS=-O OTHERLIBS=-lc_s".
                   21790: LDOPTS is used in the Makefile where the ksh is actually built.
                   21791: 
                   21792: The very first time on a new system, do a "make clobber"
                   21793: 
                   21794: Good luck.
                   21795: 
                   21796: Documentation
                   21797: -------------
                   21798: 
                   21799: The ksh.1 is a man page for the PD ksh, although it lags
                   21800: somewhat behind the code.  You get what you pay for.
                   21801: 
                   21802: The ksh88.1 is a man page for AT&T's ksh88 (the latest version)
                   21803: provided for comparison.
                   21804: 
                   21805: History
                   21806: -------
                   21807: 
                   21808: Much of the shell was written by Eric Gisin at the University
                   21809: of Waterloo, using some pieces of other stuff, notably Charles
                   21810: Forsythe's V7 shell, and some enhancements from the BRL shell.
                   21811: He placed it (in a alpha test state) into the public domain
                   21812: while I was at UW.  I snarfed a copy, and got it running on my
                   21813: UNIXpc, and later some machines at work.  I sent Gisin some bug
                   21814: reports, but he seems to have lost interest in the project.
                   21815: This may be because he now does some work for MKS, who produce a
                   21816: commercial version of the ksh for MS-DOS machines, so there may
                   21817: be a conflict of interest.
                   21818: 
                   21819: So I gave up on getting future versions, and adopted it.  I've
                   21820: made some enhancements, and quite a few bug fixes, and various
                   21821: people at work have contributed as well.  It remains in the
                   21822: public domain, although I imagine the people involved would
                   21823: appreciate leaving their names attached (I'm exempt; I haven't
                   21824: actually included my name anywhere but here).
                   21825: 
                   21826: The README in the sh directory is Gisin's, and tells a bit of
                   21827: the story from his point of view.  Note that his compilation
                   21828: instructions don't really apply anymore.
                   21829: 
                   21830: John R. MacMillan
                   21831: ./pdksh/MANIFEST   644    653   1762       10307  5243743645  10567 0ustar  hlu   File Name          Archive #       Description
                   21832: -----------------------------------------------------------
                   21833:  ChangeLog                 1   Current change history
                   21834:  Changes.jrm               1   
                   21835:  Changes.pc                1   
                   21836:  Changes.mlj               1   
                   21837:  INSTALL                   1   Installation notes
                   21838:  MACHINES                  1   Systems the shell has been built on
                   21839:  MANIFEST                  1   This shipping list
                   21840:  Makefile                  1   
                   21841:  PATCHDATES                1   C-News style patch tracking
                   21842:  README                    1   Please read
                   21843:  ReadMe.jrm                1   General info and Install instructions
                   21844:  ReadMe.sjg                1   
                   21845:  ReadMe.vimode             1   
                   21846:  bug-report                1   Bug report template
                   21847:  etc                       1   
                   21848:  etc/ksh.kshrc             1   global .kshrc
                   21849:  etc/profile               1   
                   21850:  etc/sys_config.sh         1   
                   21851:  ksh.1                     2   Manual page
                   21852:  sh                        1   ksh source
                   21853:  sh/ChangeLog              2   Current change list
                   21854:  sh/Changes                1   
                   21855:  sh/Makefile               2   
                   21856:  sh/ReadMe                 1   Original ReadMe (out of date)
                   21857:  sh/alloc.c                2   
                   21858:  sh/alloc.h                1   
                   21859:  sh/c_ksh.c                3   
                   21860:  sh/c_sh.c                 3   
                   21861:  sh/c_test.c               3   
                   21862:  sh/config.h               1   
                   21863:  sh/edit.c                 3   
                   21864:  sh/edit.h                 3   
                   21865:  sh/emacs.c                4   
                   21866:  sh/eval.c                 4   
                   21867:  sh/exec.c                 5   
                   21868:  sh/expand.h               3   
                   21869:  sh/expr.c                 3   
                   21870:  sh/getopts.c              5   
                   21871:  sh/history.c              5   
                   21872:  sh/io.c                   5   
                   21873:  sh/jobs.c                 6   
                   21874:  sh/lex.c                  5   
                   21875:  sh/lex.h                  5   
                   21876:  sh/mail.c                 6   
                   21877:  sh/main.c                 6   
                   21878:  sh/misc.c                 6   
                   21879:  sh/patchlevel.h          6    version/patch level.
                   21880:  sh/proto.h               1    Prototypes for ANSI compilers.
                   21881:  sh/sh.h                   6   
                   21882:  sh/sigact.h              6    Header for sigaction() implementation.
                   21883:  sh/sigact.c              6    sigaction() implementation.
                   21884:  sh/stdh.h                 6   Centralise std header inclusion.
                   21885:  sh/syn.c                  7   
                   21886:  sh/table.c                7   
                   21887:  sh/table.h                7   
                   21888:  sh/trace.c                7   Simple trace facilty
                   21889:  sh/trace.h                7   
                   21890:  sh/trap.c                 7   
                   21891:  sh/tree.c                 7   
                   21892:  sh/tree.h                 7   
                   21893:  sh/tty.h                  1   
                   21894:  sh/do_ulimit.c            7   
                   21895:  sh/var.c                  8   
                   21896:  sh/version.c              3   
                   21897:  sh/vi.c                   8   
                   21898:  std                       1   libraries
                   21899:  std/Makefile              3   
                   21900:  std/mklinks               1   make symlinks
                   21901:  std/posix                 2   
                   21902:  std/posix                 4   posix lib source
                   21903:  std/posix/ChangeLog       4   change history
                   21904:  std/posix/Makefile        5   
                   21905:  std/posix/dirent.C        7   
                   21906:  std/posix/dirent.H        7   
                   21907:  std/posix/dirent.h        7   
                   21908:  std/posix/dup2.c          7   
                   21909:  std/posix/fcntl.c         7   
                   21910:  std/posix/fcntl.h         7   
                   21911:  std/posix/fixincludes     8   
                   21912:  std/posix/io.h            8   
                   21913:  std/posix/time.h          8   
                   21914:  std/posix/times.c         8   
                   21915:  std/posix/times.h         8   
                   21916:  std/posix/unistd.c        9   
                   21917:  std/posix/unistd.h        9   
                   21918:  std/posix/wait.h          9   
                   21919:  std/stdc                  5   stdc lib source
                   21920:  std/stdc/ChangeLog        7   change history
                   21921:  std/stdc/Makefile         9   
                   21922:  std/stdc/clock.c          9   
                   21923:  std/stdc/fprintf.c        9   
                   21924:  std/stdc/limits.h         9   
                   21925:  std/stdc/memchr.c         8   
                   21926:  std/stdc/memcmp.c         9   
                   21927:  std/stdc/memcpy.c         9   
                   21928:  std/stdc/memmove.c        9   
                   21929:  std/stdc/memset.c         9   
                   21930:  std/stdc/setvbuf.c        9   
                   21931:  std/stdc/sprintf.c        9   
                   21932:  std/stdc/stdarg.h         9   
                   21933:  std/stdc/stddef.h         9   
                   21934:  std/stdc/stdio.c          9   
                   21935:  std/stdc/stdio.h_std      9   
                   21936:  std/stdc/stdio.sed        9   
                   21937:  std/stdc/stdlib.h         9   
                   21938:  std/stdc/strcat.c         9   
                   21939:  std/stdc/strchr.c         9   
                   21940:  std/stdc/strcmp.c         9   
                   21941:  std/stdc/strcpy.c         9   
                   21942:  std/stdc/strcspn.c        9   
                   21943:  std/stdc/strerror.c       9   
                   21944:  std/stdc/string.h         9   
                   21945:  std/stdc/strlen.c         9   
                   21946:  std/stdc/strncat.c        9   
                   21947:  std/stdc/strncmp.c        9   
                   21948:  std/stdc/strncpy.c        9   
                   21949:  std/stdc/strpbrk.c        9   
                   21950:  std/stdc/strrchr.c        9   
                   21951:  std/stdc/strspn.c         9   
                   21952:  std/stdc/strstr.c         9   
                   21953:  std/stdc/strtok.c         9   
                   21954:  std/stdc/time.h           9   
                   21955:  std/stdc/types.h          9   
                   21956:  std/stdc/vprintf.c        9   
                   21957: ./pdksh/Changes.jrm   644    653   1762        4477  5243742753  11512 0ustar  hluChanges to the PD ksh since last time:
                   21958: 
                   21959: - clean up the option configuration stuff.  Options in config.h should
                   21960:   now just be #define'd or not, not #define'd to 1 if you want them
                   21961:   and 0 if you don't
                   21962: 
                   21963: - ksh now uses the shell specified by the variable EXECSHELL to run
                   21964:   shell scripts.  If EXECSHELL is unset or null it defaults to
                   21965:   /bin/sh.  It does a path lookup on the value, so if you set it to
                   21966:   ``ksh'' the ksh will run all scripts that don't start with #!.  It
                   21967:   seems to run most sh scripts fine (now).  I'd be very interested to
                   21968:   hear your experiences if you try this out, as for my next trick I'd
                   21969:   like to make ksh just fork itself to run scripts, which would speed
                   21970:   things up, and allow exportable functions and aliases (like he real
                   21971:   ksh).  Just to assure you that it can do some hairy sh scripts, both
                   21972:   CC and coco work with ksh.
                   21973: 
                   21974:   EXECSHELL won't work if the system's exec(2) call runs scripts...
                   21975: 
                   21976: - the ``let'' builtin now evaluates null or unset vars to 0, as per
                   21977:   The Book
                   21978: 
                   21979: - Various memory allocation/use problems were cleaned up.  Hopefully
                   21980:   you'll never see the ``freeing free object'' error again (if you've
                   21981:   ever seen it).
                   21982: 
                   21983: - the ``test'' builtin is now much more tolerant in parsing its
                   21984:   arguments.  This was to make it like the /bin/sh test.
                   21985: 
                   21986: - Temp files (for here documents or ``fc'') are now mode 0600
                   21987: 
                   21988: - Some format strings in the tree printing routines got ``expanded''
                   21989:   into SCCS keywords, so the results of``type <function>'' were
                   21990:   gave you interesting things like the time I last checked in the
                   21991:   file.  This has been fixed.
                   21992: 
                   21993: - ``unset -f'' now really does unset functions.
                   21994: 
                   21995: - the ``trailing blank or tab in alias definition'' feature now works.
                   21996: 
                   21997: - A bug in command completion was fixed.  Note command completion only
                   21998:   works on commands that have been hashed, so you want to ``set -h''
                   21999:   in your .kshrc, and you may wish to force hashing of some common
                   22000:   commands with the ``hash'' builtin.
                   22001: 
                   22002: - ``echo $$ | cat'' now works as in /bin/sh
                   22003: 
                   22004: Not new features, but newly discovered bugs:
                   22005: 
                   22006: - Local functions don't work correctly.  This shouldn't be much
                   22007:   problem, since sh doesn't have them.
                   22008: 
                   22009: - Here documents in functions don't work.  This is a problem with the
                   22010:   temp file allocation that requires more work to fix than I've gotten
                   22011:   around to doing.  So avoid things like:
                   22012: 
                   22013: foo() {
                   22014:        cat <<- HereDoc
                   22015: This is a test
                   22016: HereDoc
                   22017: }
                   22018: ./pdksh/ReadMe.sjg   644    653   1762        5273  5243742753  11265 0ustar  hluHORIZONTAL SCROLLING
                   22019: ====================
                   22020: 
                   22021: I have migrated my 3.2 ksh edit.c mods into the 3.3 ksh
                   22022: This file describes the mods in general and really only applies
                   22023: (at this stage) to emacs-mode.  I have not touched vi-mode apart
                   22024: from making it use pprompt() so that '!' is correctly expanded
                   22025: as in emacs-mode.
                   22026: 
                   22027: I would prefer to see both vi.c and emacs.c use a common set of
                   22028: primatives in edit.c - but that looks like a lot of work.
                   22029: 
                   22030: Basically my mods affect the functions that move the cursor
                   22031: about and redraw the edit line.  
                   22032: 
                   22033: The input buffer "buf" is pointed to by "xbuf" and its end is
                   22034: pointed to by "xend".  The current position in "xbuf" and end of
                   22035: the edit line are pointed to by "xcp" and "xep" respectively.
                   22036: I have added "xbp" which points to the start of a display window
                   22037: within "xbuf".
                   22038: 
                   22039: [A] starting position
                   22040: 
                   22041: buf
                   22042: |<-------- $COLUMNS --------->|
                   22043: |    |<---- x_displen ------->|
                   22044: | PS1|
                   22045:      +==========+==============--------+.......+
                   22046:      |\          \                      \       \
                   22047:   xbuf xbp        xcp                    xep     xend
                   22048: 
                   22049: [B] scrolled
                   22050: 
                   22051: buf
                   22052: |           |<----- COLUMNS -------->|
                   22053: |           |<----- x_displen ------>|
                   22054: |      
                   22055: +-----------+==========+==============--------+.......+
                   22056:  \           \          \                      \       \
                   22057:   xbuf        xbp        xcp                    xep     xend
                   22058: 
                   22059: In the above -------- represents the current edit line while
                   22060: ===== represents that portion which is visible on the screen.
                   22061: Note that initially xbp == xbuf and PS1 is displayed.
                   22062: PS1 uses some of the screen width and thus "x_displen" is less
                   22063: than $COLUMNS.
                   22064: 
                   22065: Any time that "xcp" moves outside the region bounded by "xbp"
                   22066: and "xbp" + "x_displen", the function x_adjust() is called to
                   22067: relocate "xbp" appropriately and redraw the line.
                   22068: 
                   22069: Excessive I/O is avoided where possible.  x_goto() for instance
                   22070: calculates whether the destination is outside the visible
                   22071: region, and if so simply adjusts "xcp" and calls x_adjust()
                   22072: directly.  Normally though x_adjust() is called from x_putc().
                   22073: 
                   22074: The above mechanism has be updated to use a function x_lastcp()
                   22075: that returns a pointer that accurately  reflects the last
                   22076: visible char in the edit buffer.  That is a more accurate
                   22077: version of xbp + x_displen which does not account for TABS.
                   22078: 
                   22079: Other changes
                   22080: =============
                   22081: 
                   22082: I have also added some emacs mode functions.
                   22083: M-[0-9]
                   22084:        Set a numeric arg (positive only).
                   22085:        Used by all word related commands.
                   22086: M-_
                   22087: M-.
                   22088:        Retrieve word from previous command (default is last
                   22089:        word).  Use M-[1-9] to select word.
                   22090: M-u
                   22091: M-l
                   22092: M-c
                   22093:        UPPER,lower,Capitalize word.
                   22094: 
                   22095: 
                   22096: Commands like delete-word now push the deleted text so that it
                   22097: may be yanked back into place.
                   22098: 
                   22099: BUGS?
                   22100: =====
                   22101: 
                   22102: There are bound to be some.  Please report same to me:
                   22103: 
                   22104: Simon J. Gerraty       <[email protected]>
                   22105: 
                   22106: ./pdksh/Makefile   644    653   1762        1420  5243743646  11053 0ustar  hlu# PD Bourne/Korn Shell
                   22107: # $Id: Makefile,v 1.3 1992/08/10 11:59:10 sjg Exp $
                   22108: 
                   22109: SHELL = /bin/sh
                   22110: MAKE  = make
                   22111: CC=gcc -pipe -g -O
                   22112: LN=ln -s
                   22113: #LN=ln
                   22114: #CONFIG= -D_SYSV
                   22115: CONFIG= -D_BSD 
                   22116: #CONFIG= -D_BSD -DHAVE_SYS_STDTYPES
                   22117: #CONFIG= -D_V7
                   22118: #CONFIG= -D_ST                         # Atari ST
                   22119: #CONFIG= -D_BSDI -D_POSIX_TERM         # BSD/386
                   22120: MANPAGES = ksh.1
                   22121: #MANDIR=/usr/catman/u_man/man1
                   22122: #MANDIR=/usr/man/man1
                   22123: 
                   22124: #INSTALL=bsdinstall
                   22125: INSTALL=install
                   22126: 
                   22127: all:   ksh
                   22128: 
                   22129: ksh:   libs
                   22130:        ( cd sh ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' $@ )
                   22131: 
                   22132: libs:
                   22133:        ( cd std ; $(MAKE) 'CC=$(CC)' 'CONFIG=$(CONFIG)' 'LN=$(LN)' libs )
                   22134: 
                   22135: install: sh/ksh
                   22136:        ( cd sh ; $(INSTALL) -s ksh $(DESTDIR)/bin )
                   22137: 
                   22138: sh/ksh:        ksh
                   22139: 
                   22140: inst-man: $(MANPAGES)
                   22141:        $(INSTALL) -c -m 444 $(MANPAGES) $(MANDESTDIR)/man1
                   22142: 
                   22143: clean clobber:
                   22144:        ( cd std ; $(MAKE) $@ )
                   22145:        ( cd sh ; $(MAKE) $@ )
                   22146:        -rm -f *.out
                   22147: 
                   22148: ./pdksh/ReadMe.vimode   644    653   1762        2445  5243742767  11770 0ustar  hlu
                   22149: The changes I have made are all relevant to the VI edit mode. The vi-edit
                   22150: source seems mostly complete, so these changes are minimal. What is available
                   22151: now is pretty useful. I will make further fixes as I notice the bugs (or
                   22152: anyone else does).
                   22153: 
                   22154: A summary of changes follows:
                   22155: 
                   22156: 1) two changes to turn on the vi-editing feature.
                   22157: 2) motion edit fix: back space and space bar now do something: have
                   22158: the same behaviour as the 'h' and 'l' keys.
                   22159: 3) input edit fix: backspace key now works.
                   22160: 
                   22161: Known bugs (not fixed yet):
                   22162: 
                   22163: a) proviso on 1) and 2) above: the backspace key was hardwired to the
                   22164: <delete> key. I have temporarily extended it to include the '^H' or
                   22165: <backspace> key. I will generalize this to use whatever key is defined
                   22166: as the erase character by stty.
                   22167: 
                   22168: b) the interrupt key does not clear the edit buffer. This means the next
                   22169: edit command after an interrupt will be garbage.
                   22170: 
                   22171: c) Same sort of thing as b) occurs for the <EOF> key.
                   22172: 
                   22173: d) insertions near the beginning of an edit buffer seem to screw up the rest
                   22174: of the buffer.
                   22175: 
                   22176: Known missing features:
                   22177: 
                   22178: a) search edit commands: [count]-, [count]+
                   22179: b) text modification edit commands: P, p, *
                   22180: c) r (replace) doesn't seem to work too well.
                   22181: d) tilde does not do anything (should reverse upper to lower and vice versa)
                   22182: 
                   22183: e) ! in prompt doesn't get expanded to history number
                   22184: ./pdksh/bug-report   644    653   1762        2037  5243743673  11431 0ustar  hluTo: [email protected]
                   22185: Subject: [area]: [synopsis]   [replace with actual area and short description]
                   22186: 
                   22187: VERSION:
                   22188:     PD KSH: 4.7 12-Aug-92
                   22189:     [Official patches will edit this line to indicate the patch level]
                   22190: 
                   22191: MACHINE and OPERATING SYSTEM:
                   22192:     [e.g. Sparc/SunOS 4.1.1, DECstation 3100/Ultrix 4.2, ...]
                   22193: 
                   22194: COMPILER:
                   22195:     [e.g. native cc, native ANSI cc, gcc 1.40, ...]
                   22196: 
                   22197: AREA:
                   22198:     [Area of the source tree affected,
                   22199:      e.g., std/posix, std/stdc, sh]
                   22200: 
                   22201: SYNOPSIS:
                   22202:     [Brief description of the problem and where it is located]
                   22203: 
                   22204: DESCRIPTION:
                   22205:     [Detailed description of problem.  Please provide as much detail
                   22206:      as you can manage.  The more information we have the more likely 
                   22207:      a fix]
                   22208: 
                   22209: SAMPLE FIX:
                   22210:     [Preferred, but not necessary.  Please send context diffs (diff -c)
                   22211:      name old file first.  eg. diff -c file.c.old file.c]
                   22212: 
                   22213: [PLEASE make your Subject: line as descriptive as possible.
                   22214:  Subjects like "pdksh bug" or "bug report" are not helpful!]
                   22215: [Remove all the explanatory text in brackets before mailing.]
                   22216: [Send to [email protected]]
                   22217: ./pdksh/Changes.pc   644    653   1762        2110  5243743644  11302 0ustar  hluChanges by Peter Collinson - Hillside Systems/BSDI - July 1992
                   22218: 
                   22219: 
                   22220: a)     Add select command - this cannot be ksh without that.
                   22221:        (It NEEDS typedefs too)
                   22222: b)     Remove all the bcopys from vi.c
                   22223:        add 
                   22224:        #define memmove in sh.h for BSD systems
                   22225: c)     Add <Esc>* command to vi mode - expands to a list of files
                   22226:        using the menu printing routine
                   22227: d)     Add my version of history, that works much like the `proper' ksh
                   22228:        storing data in a file that is shared between different invocations
                   22229:        of the shell.
                   22230: e)     Add the ability to redirect to am expansion... ie
                   22231: 
                   22232:                ls > o*
                   22233:        if o* is unique then it puts it into the file that matches
                   22234:        otherwise it puts it to a file called o*... this is current
                   22235:        behaviour.
                   22236: f)     Add alternations, from Csh.d) This is not part of ksh but is something
                   22237:        that csh users really miss from the Bourne shell derivatives. The idea
                   22238:        is that lists inside curly braces expand to arguments. ie.
                   22239:                exampl{a,b,c,d,e}
                   22240:        will expand to 5 arguments
                   22241:                exampla examplb examplc exampld example
                   22242:        Recursive lists are permitted.
                   22243: g)     Add suspend as a built-in alias.
                   22244: h)     Port to BSD/386 - add _POSIX_TERM and _BSDI as defines.
                   22245: ./pdksh/ksh   755    653   1762      262000  5302770105  10153 0ustar  hlu&P&X��C&�-�̀�\   `�-:�D$�4  `�:P�`[�&̀��r$Id: version.c,v 1.6 1992/08/12 14:15:53 sjg Exp $$Id: main.c,v 1.6 1992/08/12 14:15:39 sjg Exp $${SHELL:=/bin/sh} ${PATH:=/bin:/usr/bin:.} ${HOME:=/} ${PS1:=$ } ${PS2:=> } ${PS3:=#? } ${MAILCHECK:=600}cd.typeset-xSHELLPATHHOME-rPWDOLDPWD-iSECONDS=0OPTIND=1aliasinteger=typeset -ipwd=print -r "$PWD"history=fc -lr=fc -e -nohup=nohup login=exec loginnewgrp=exec newgrptype=whence -vfunctions=typeset -fecho=printtrue=:false=let[=\[suspend=kill -STOP $$PPIDRANDOM# PS1r%s: cannot open
                   22246: /etc/profile.profileENV��UWVS�\$,�D@&�D$�D$�<_&��^&��^&�(_&�@_&��^&��^&�,_&��^&�|^&&�$_&��h�b&�&����^&h�^&�&����^& d&��^&��^&� j�!&��j&�!&��j�!&����
                   22247: &h�b&h_&�&��h�b&hb&�&��h�b&h�^&�&��h�b&h�`&�&���   &��t�;t���3�&&�����;u��m`�t^&jjh0P&��&��jjhP&��&���i!1��=��t!�������t��3�������F�;u�1��=��t!�������t��3�ͦ����F�;u�jh��}"&����&`Pjjh#�^&��P��&��jh&h#�A&��j��
                   22248: `��Pjjh(�%&��P�&���8P&�=8P&t6�����;t�h�^&�3��������;u�V�����s�{u�h�^&�&���{`f��uh/h2�        &��P�
&��j�/���Ë=`b&�{1�L$(�9�|$�&�|$$&�&�A�8-uq�x&tk�QB��:t]���L$����<ct<qt&�0�&9t$$~6�C�L$�9�;�D$F����D$&�����<w        ����c&B�:u��{��9t$$~}�=d&ut�L$(�<��|$�{Fh6�t$�c��_���C��u�t$h8��&���D$&�s� ��_��P�&��P�s��`��hjj�s�`���{u]�s����_����u�d&&j�A&`����t j&�3&`����t��u�|$u�       d&&�=  d&t�=d&t�C&�{&u%j
                   22249: jj���_���tQ&j&jP���_���:R荮�|$u
                   22250: j�'����L$(���(d&�|$$)��=$d&�(d&�L$�����|$�?-u!�  d&&hI���hV���j h_�z&��P�e
                   22251: &��P�`&���€:t   R����=     d&t$jh$_&j�v`��j�����T5� ���d&&�{&u�
d&&�g��=   d&t   S�x&��S�����D$$�t$$���1�[^_]���-UWVS�l$������tMh6U�B��_���Å�u    1�[^_]Ð�S���_��P�&��PS��`��hjjS�`����`b&j�G,���X�hP�L��9`b&t S�K��_���&[^_]�S�\$j�,���P���[�
                   22252: Use `exit'
                   22253: ��VS�t$�D$
�D$j&�8����^&&�a&h�^&���_����t8�$b&��t
h��     &���D$��t�~&u     �~t�N��R&��$b&��t���=    d&tjh$_&j�`���~u
                   22254: �d&�V�g��~&��%��D$��u�~u+jh2�%&��P�&��P�&���_&�4&�D$&V������D$�f���tB�;u=�D$��te�=d&t\�D$H�D$�D$��~Kh��
&���F&������j�Q&���=d&t�~&ujS�����&��������&�a&[^��Ã=�^&u�=�^&t�Qh�R&�۽���=       d&t�&����t$���_����=d&u   �=      d&u
                   22255: j&����������^&��&t��t�.����t�%�j&�u�����j&h�^&�n��_��j&h�^&�`��_�[빐WVSh�^&j4��&���É߾�^&��
�h�^&�?&���L$�
�^&��^&��^&��^&[^_�UWVS�-�^&��u�5a&�/��_����M9
�^&t��&�=�^&t1ې��^&�XPS�&��C��       ~��"��^&����
�h�^&U�4&��[^_]�S��^&��t��s��`�����u���^&h�^&�w&��[�alloc internal error: %s
                   22256: �t$h6�&���$Id: misc.c,v 1.3 1992/08/12 14:15:42 sjg Exp $S�T$�\$��}�a&�b&�� @9�~��
a&����a&B�:u�[�0123456789     
                   22257: |&;<>()*@#!$-?=-+?#%�ea&�~a&���&@9�~��Ea&�^a&���&@9�~��
ca&&jh��e�����jh��V�����jh��G�����j@h��8������0123456789ABCDEFS�D$�\$��V&��V&���I1���`
���u��[���W�L$��u1�_��ÐQ�t$0҉ψ���������щL$�t$�:&���D$�t$�6`���D$�D$_���allexportbgniceemacserrexithashallignoreeofinteractivekeywordmarkdirsmonitornoexecnoglobnounsetprivilegedstdintrackallverbosevixtraceVS�t$��P&�=�P&t V�3�`��_����u     �C[^Ð�����;u�1�[^�����a�����c&t�Ј&AB��z~��&h�^&�D$P���������%s 
                   22258: S��P&�=�P&t$��C��d&t�3h      �&�����;u�h
��&��[�%s: bad number
                   22259: VS�t$��>-u�N&1������\B�A�&��a&$u�9tVhR�|&���؀>-u��[^�VS�t$�\$��t>��u~�8�F���uo�C<?t$<*t*�T<[uP��tRS�q���Å�uL�����uD1�[^Ð��N����;tSV��������t      �&[^Ð�F��u��ϐ���C�9�t��9�u��C���x����>��%�[^�WVS�T$�|$1�1ۀ:�u
                   22260: B�:!���؅�tB��:�u&B�:t=�
                   22261: �z&-u�z]t
                   22262: �BB������9�t      9��&B�:]u�9�t�B&[^_Ð�1�[^_Ð�1�[^_��T$�t$�L$��&�PR����UWVS�D$+D$������&����"&�L$�<����t$�l$�����9�s,�3�6�L$$�у���u��������ސ���}���Ӑ��9�vd�u�7�L$$�у���u����M��E�ې����~49�u����M���M�����븋�M��E������s���������뛐��9�uT��+T$���D$)���9�|�t$�t$�GP� ������\$�&�����t$S�t$����������|$������������E��M��������������[^_]��t$�t$����_���/UWVS�|$�\$�Q1��ڀ?/t&�L$���&�AB��u��C9�r�z�/uJ����B�/���9ti��&�AB</uC�C&9�v<�z�/uJ�3���z�.u+�z�/u���� ����z�.u�B��z�/u�9�vH�8/u��P&�9u���u��y�/t��&��땐���z�/u   �B�9�v���[^_]�$Id: syn.c,v 1.3 1992/08/10 12:03:10 sjg Exp $��V&�,b&��V&&j�G����V&��uj� ����V&1�Ð�g&��V&jj
                   22263: �&���=,b&��%��WVS1��t$����Dž�����=�V&t��V&��V&���j������V&��|uHj&�Q���Å�u����ujSWj�$���lj�룐��jS�vj����F��뉐��V&&��[^_�WVSj�R������Dž�����=�V&t��V&�5�V&��j�!����V&�Ɓ�&&t��&u;j&�������Å�u�.jSW���&&u�P�j����닐����V&&��[^_�VS1��W����ƅ�����=�V&t��V&��V&���j�����V&��;t%��&t%�=L_&u��`&�zt�zu|��
                   22264: uw��&u+��tjj�sj�����C�jjVj������������u��[^Ð��ujPVj����Ɖ��Q����jP�sj����C���6�������V&&��[^�too many <<'s
                   22265: S�=�V&t
                   22266: ��V&������V&&�t$�����V&=&t1�[Ð���V&�P_&jh&�P���P_&�S�C����u4�=�b&t�K�=\b&\b&r
h��
&���\b&��\b&��[��=�V&t��V&��V&����t$������V&9D$t��WVS�|$�\$�L_&������jS�������
L_&jjVW�8
��[^_�too many redirectionsunexpected EOFletinvalid function name
                   22267: ��UWVS�|$01�h�^&j,�       &���D$h�^&j@�      &���D$$�D$ ��@�D$(h�^&j@�n   &���D$�D$��@�D$�=L_&t�&���t$���W�&������Å�t��   ~
h�~�����E����ԃ=�V&t��V&��V&��W�����V&�Á�&��J��{����t��(�z����&�|��&���l��        &��^����&����
&F����&td��&�f�(��&�$���h1���1�[^_]����V&&��u
                   22268: 1�[^_]���j&������~�����V&&j&����ǁ�&����V&�T$(9T$ r9�\$ +\$$��h�^&��P�t$,�
     &���D$$����&‰T$ &Ӊ\$(�D$ �@�D$ jh&�������T$(9T$ r9�\$ +\$$��h�^&��P�t$,�&���D$$����&‰T$ &Ӊ\$(�D$ �P_&��D$ �T$�4��=�V&t��V&���V&&j�����V&=&t =&t;�U��=&�&�C��   ~
h���j���������E���V&�D$ +D$$��t �=d&tlj=h�b&�x��_����tY�T$9T$r9�\$+\$��h�^&��P�t$ �&���D$����&‰T$&Ӊ\$�D$�P_&��D$�����T$(9T$ r9�\$ +\$$��h�^&��P�t$,�Q&���D$$����&‰T$ &Ӊ\$(�D$ �P_&��D$ ���������V&�D$ +D$$����&t�
                   22269: �=�b&u
hD����j�
                   22270: ����h�^&h�b&�������Gj  j{�������j}j�)������G��[^_]��Ðj)j���j}j���������&����&u�P�   ����jh&������h�^&h�b&�������G�L_&��Gj�����G�
L_&�8&��L_&���&u�P�:   ���������Gj&����G�
L_&���j       �
      ����jh&��������P_&�W�L_&j  h&���������Gjh
                   22271: &�+���L_&j
                   22272: ������    ����G��Gjh&�������
L_&�n���j&��������jjWj������L�j�e����jh&�T�����h�^&h�b&�B������Gj       j{�3�����j}j�c������G�T$�4���j�i������Å�t��    ~
h�������E�֐���uh�^&�t$�b&���G�-���T$��h�^&��P�t$�s&���T$�W�?&���T$(9T$ r9�\$ +\$$��h�^&��P�t$,�5&���D$$����&‰T$ &Ӊ\$(�D$ ��D$ h�^&�D$$+D$($�P�t$,��&���G�T$9T$r9�\$+\$��h�^&��P�t$ ��&���D$����&‰T$&Ӊ\$�D$��D$h�^&�D$+D$$�P�t$ �&���G�"h�^&�t$(�.&��h�^&�t$�&����[^_]���S�=�V&t��V&��V&��j      �y����V&=&u�|$t1�[Ð��=&t�������jh&�)�������[�S�=�V&t��V&��V&��j�����V&=&t��V&&1�[�j�������'����C��u��
                   22273: �C��[�S�=�V&t��V&��V&��j�����V&=&t
                   22274: =&t�5�������Å�u%����j
�]���������C�+����C��[���V&&1�[�VS1�1����=�V&t��V&���V&&j      �����V&=
                   22275: &t �#��u�É��F뺐��C��뱐��[^���VSh�^&j@�3&���D$�D$��@�D$j����ƻ  �=�V&t��V&��V&���j        �����V&��(t��V&&�1ې�Sh&�U������T$9T$r9�\$+\$��h�^&��P�t$��&���D$����&‰T$&Ӊ\$�D$�P_&��D$1ۃ=�V&t��V&��V&���j������V&��|�h�����V&&�T$9T$r9�\$+\$��h�^&��P�t$�[&���D$����&‰T$&Ӊ\$�D$��D$h�^&�D$+D$$�P�t$�&���Fjj)�D����������F�=�V&t��V&����V&&j   �+����V&=
                   22276: &tj h&���������[^�����Sh�^&j@�P����D$�D$��@�D$�=�V&t��V&��V&�j     ������V&=&t��V&&1�[��Ð�=�V&t��V&��V&���j�}����V&=&uZ�T$9T$r9�\$+\$��h�^&��P�t$������D$����&‰T$&Ӊ\$�D$�P_&��D$�u������
                   22277: t
                   22278: ��;t�A�D$+D$����uh�^&�t$�\���1�[��Ð��T$9T$r4h�^&��P�t$�p����D$����T$�T$&ЉD$�D$��D$h�^&�D$+D$$�P�t$�*���[���WVS�\$�t$�|$�t$�@&���X�p�x[^_�forselectcaseesacwhiledodoneifinthenelseelifuntilfifunctiontime{}t$&x$&$    &�$
                   22279: &�$&�$&�$&�$&�$&�$&�$&�$&�$
&�$&�$&�$&�${�$}S��$�=�$t3��3����P�3h�^&�5�����@�S�P���;u�[�S�\$h�^&j�_�����@�@�@�@�@�@[�syntax errorh�%�n���S�\$�,b&�L_&�\b&4b&��`&������t�����CH��&v�{u�TV&��V&[�$Id: lex.c,v 1.3 1992/08/10 12:02:55 sjg Exp $no closing quoteexcessive recusrsive aliasing��dUWVS�l$4�=PW&tC�PW&��Q&�
�Q&��~ �����Q&��W&� �����
�Q&�����Q&�D$0@h�^&jH������D$$��L$0�L$ �ƊD$x$t
                   22280: �D$�s�D$x$t�D$�a���D$��`&��8t�8���
�ǃ� t���       tۃ�#u&����`&��8t�8���_
�Dž�t��
                   22281: uܡ�`&��=TW&t�TW&�L$x�L$�L$�L$�M����`&��8t�8���
�Dž����|$u����%���a&$�e9t$ w:�\$$�L$0&L$0h�^&�D$4��PS�"����D$$��L$0�L$ ��)؉�t$$�9D$�p����L$�$��(��(l,x,�,�,�,)P-��'tK   ��"tT�j����\uh��`&��8t
                   22282: �8��
                   22283: ����7�ǃ�
                   22284: t��`9t$$�%���������E�D$&�E&��E�D$�E�F���������\t#��\��$�����`������`&��8t�8����ǃ�$�t�����
                   22285: �u�����"�`��������\�S�����`�J���9t$ w:�\$$�L$0&L$0h�^&�D$4��PS�����D$$��L$0�L$ ��)؉�t$$�&F�\F�&�b����`&��8t�8����ǃ�(uE�D$�E�O����{�'&E�D$�E�F��`&��8t      �8��
                   22286: ���
                   22287: �ǐ9t$ w:�\$$�L$0&L$0h�^&�D$4��PS������D$$��L$0�L$ ��)؉�t$$���ȈF��`&��8t�8����[
                   22288: �lj����Š�a&$u��F��}�{&��#t��%u5��`&��8t�����
                   22289: 9�u�π�A��`&��5��:u+��F��`&��8t����
                   22290: �����  ���������F�������L$�ъ�a&$&���F�9t$ w:�\$$�L$0&L$0h�^&�D$4��PS������D$$��L$0�L$ ��)؉�t$$���ȈF��`&��8t�8����G �lj���%���a&$u��F��h���a&
                   22291: tW9t$ w:�\$$�L$0&L$0h�^&�D$4��PS�^����D$$��L$0�L$ ��)؉�t$$�F�L$�F�F�����&F�$F��`&�����E�D$�E�F�z�������'t�b�������"�����M�M�L$�F�Q������(uE�L$�M����)u      M�M�L$�|$���F��������}�����M�M�L$�F�&������`u�FM�M�L$��������\u@��`&��8t
                   22292: �8��
                   22293: ������ǃ�\t��
                   22294: �������$t
�����`t�\F���ȈF���������)�������`&��8t
                   22295: ���������)t��`&�������1�9t$ w:�\$$�L$0&L$0h�^&�D$4��PS�����D$$��L$0�L$ ��)؉�t$$�L$9L$t
h�&�����<t��>u8�T$$9�v!�:&u�B&��a&$t���F&���������>��%��D$9t$$�'�|$�h�^&V�������;t=��(��&%��
                   22296: �&��&t"���>tk    ��<td�����|t��[^_]��dÐ��`&��8t����g9���&��;t��|t�,&��&u�&&�
�&���&��먐��h�^&j�0����ËL$���`&��8t��D$��
                   22297: ����D$�|$>t�|$<uM9|$u��>u
                   22298: �C���C�
                   22299: ����C��`&��8t��D$��$���D$����>u�C�   ���C&�{u�|$-u4�C$�2����|$&u        �C��|$!u�{u�CB�  ����`&��P_&�&[^_]��dÐ��'�D$x$&�����
                   22300: [^_]��dÐ���`&��8t��D$��   ���D$�|$)u�&�K������|$(u
�&�8��������`&��)����Fh�^&��+D$(P�t$,������P_&�D$�����&w�&[^_]��d���`&��P_&��b&����
                   22301: @B���b&s�8@��&t������B���b&v��t��b&�=�b&�&�D$x�
&h�b&�����Ph�b&h�^&�8��������$���{u'�D$x$th�^&�5P_&������C[^_]��d�{���D$x$��f�f% ���=�Q&uh�&��������Q&��W&��Q&� ��`&�xu�9X������@�xt�h�^&�5P_&�Z���j�����K��X�
�`&�H��`&�������&[^_]��d�S�4b&9\b&v���3�Y����9\b&w��\b&4b&[�wCannot create temporary file
                   22302: here document `%s' unclosed
                   22303: ��&UWVSj��$ &�r������h�^&�r����
�^&���^&�H��$&�Jh=2�p���_���Dž�u
h?2�9���hjjW���_���t$��`&�T$��8t�����&��
                   22304: t$��uUh]2�������$&9�s�؈F븡�`&���t$��$&�A$ t�|$ u�F��t�>      t�VU���_�����������&���W9Wr��%�PW����_���      ��G��G�F��uԋ5�`&��8t����3&�Ã�
                   22305: t<��uUh]2�1����O9Or��%�PW���_��볐���G��G릐��W9Wr��%�PW�b��_����������G��G�������W���_��[^_]��&�%s[%d]: %s
                   22306: �,b&��@��`&��`&�xt���`&�xt�p�ph\4������`&�}Q&�t$he4�^����S�\$h�^&j�?����X�}Q&�@�@�@�@[�PS2
                   22307:  VS�5�`&������9F���F�$�85��\5h5<78�7�7�7�6�7�}Q&1�[^Ð�=�b&}�F�}Q&���F��b&��b&�w&�5_&���j&�����j������=d&th&h�b&�5tQ&�3�6��=d&th&h�b&�5tQ&��h&h�b&�5tQ&����_���Å�}�4_&��u�1�ƃ�b&h�4����P�����_&��u��N�&���1ۀ=�b&t1��b&��a&}��b&BC�:t���a&|퀻�b&u���b&��N�\&���b&�P�.����F&���=�b&u�F&�}Q&�S&��F��b&��b&�xQ&����6he4�;����6h�b&���_��jh�b&����_����
                   22308: �����b&������F�vh&h�b&����_��������
`b&9N���v�s��_�������F���F�F�p�F�8u�5�F�Y��5�F�I��F�@���8t#jP�5��_���X��� t��     u
                   22309: �TW&&�v�5�`&�PW&&�+��>u�F�G�������~t�5hb&�6�m��_��������������[^�%dS�\$�;tr�;!t)�hb&�J9Jr�PCR� ��_�L���B���)���C�;!u&�hb&�J9Jrj!CR����_���B�!C�B롡�`&�phB8�~���느�5hb&�Q��_��[�$Id: edit.c,v 1.5 1992/08/10 12:02:25 sjg Exp $sttyVS�t$�\$�=�Q&*td��Q&*��b&&��c&��^&�����b&�����H_&�����b&������`&������^&&��^&�=�b&t��=�Q&tSV�5tQ&�1��_��[^Ð��j&����=d&t SV��    ��=d&tSV�U�����������j�x����~h9V���_����t
                   22310: ��b&&��}�=<     `u
                   22311: j�ȍ����[^Ã�j&�D$P�5tQ&���_����&u�D$����á4_&��uҸ��������5db&���_�����^&��^&���^&����c&)‰У�c&9(b&v�(b&��c&��Q&�5�Q&���������S�\$��
t��
                   22312: u
                   22313: ��c&�
�Q&9
�c&}S�db&�J9Jr��%�PR�y��_����B��B��t        ��t�����
                   22314: t��
u
                   22315: ��
�c&���c&�=�^&t�=�c&|��Q&���9�c&|����[�VS�\$�5�^&�;t����PC�>������;t95�^&t�[^���WVS��b&h|W&�5tQ&�D��_����W&$u
                   22316: ��Q&&�XW&�|W&�� ��kW&��^&�
lW&�L$�
b&�iW&�b&�jW&��`&�%XW&�����%dW&��nW&�oW&&PR�5H_&�t$S���[^_���S�D$9�Q&t.��Q&��Q&��thXW&��h|W&j&�5tQ&���_����[�WVS�L$1ۀ9t4�5�`&�&A<!tC����9!uAC�����F�C�
                   22317: ������9u҉�[^_�FCEDITEDITORVISUALVS1��=�Q&tC��Q&���3����P������t�8u   ��F�;uۃ<��Q&t
��t  P���1�[^�emacsviS�\$j/S���_����t�X&h]=S���_����t�d&�d&&[Ð��hc=S����_����t�d&&�d&[�$Id: emacs.c,v 1.3 1992/08/10 12:02:31 sjg Exp $auto-inserterrormacro-stringdelete-char-backwardeot-or-deletedelete-word-backwardbackward-wordkill-lineabortno-opforward-worddelete-char-forwarddelete-word-forwardbackward-charforward-charsearch-characternewlineeotup-historydown-historysearch-historybeginning-of-historyend-of-historyend-of-linebeginning-of-lineredrawprefix-1prefix-2kill-to-eolyankyank-popquotestuff-resetstufftranspose-charscompletecomplete-listlistcomplete-filecomplete-commandlist-filelist-commandnewline-and-nextset-mark-commandkill-regionexchange-point-and-markprev-hist-wordupcase-worddowncase-wordcapitalize-wordTE�=�U>�E>�F>�M->�H;>&�HP>&b�O^>\Uh>$[n>�Ht>&fG�>�H�>&d�K�>�K�>L�>|L�>
|L�>
                   22318: �L�>\Uh>�L�>�L�>�M�>�L?&<�L?&>lP,?�P8?&�PJ?8SQ?HSZ?XSc?To?�Tt?&y(S}?�U�?�U�?8R�?�^�?&_�?&�^�?&?�^�?&�^�?�^�?�^�??�M�?dZ@& tZ@�Z%@Le=@&.Le=@&_eL@&0eL@&1eL@&2eL@&3eL@&4eL@&5eL@&6eL@&7eL@&8eL@&9TfM@&UTfY@&LTfg@&CTfM@&uTfY@&lTfg@&cWVS�D$�T$�(b&��c&&‰ b&��c&��c&��c&���Q&&��W&�X&�X&TV&�=xQ&���=�W&�=�W&t�5�W&������W&�5_&�z�������c&��^&&��c&���=�Q&)lj=�^&��^&�����X&�8u��������}"��[^_Ê�X&�X&�8u
                   22319: �X&TV&�=X&�u�TE��ȃ��X&��        �Q&�����u��U���X&����      ��X&V�Ӄ��Ƹ9��c����$�EE`D$E@E`D��W&�=�����5�c&+5(b&��W&��[^_��< `�����[^_����D$��t%�D$f�T$f�T$�D$P�X��1���Ð��j�I�����1���ËT$�X&�8u�������� �Q&���X&1�Ðj�
�����1��WVS�\$�5�^&0������������Ѝx����c&9 b&wj�������[^_Ð���c&9�c&t&��+�c&@P�5�c&���c&P���_��������c&�WS�5�c&���_����c&&=�c&&=�c&��Q&�&!��c&9�c&���ƒ�&��^&S���95�^&u$��c&9�c&s�K�P����9�c&r���^&&[^_��(b&9�c&t��c&HP�"��j&�D��1�Ð�j�������1����c&9�c&tj&���1�Ðj������1��UWVS�l$���5&�=�W&t3���c&9�W&s��c&��W&����c&9�W&v)-�W&��&~ U����)-�c&�5�c&1��]����t�PF�:��&�K���u��c&+�c&@P���c&P�5�c&����_����^&�5�c&�����c&����Q&)Å�~79�~�ߍ_����t�j ������K���u��_����tj������K���u���^&&��Q&�;��95�c&s�N�P�&��95�c&r�[^_]��CP������1���/1�����c&P�[&��1���P�u�����1��S1ۋ�c&9(b&uj�������1�[Ð�=�W&et
                   22320: ��c&&�
�c&�=�c&�tP�
  `����JC9(b&t,�B��Au�z�$u���B��Au�z�$u
                   22321: JC9(b&u��
�c&�=�c&�u�R�����[�S1ɋ�c&9�c&uj�@�����1�[Ð�=�W&et
                   22322: ��c&&�
�c&�=�c&�tR�  `�9�c&t4��Cu�:$uBA9�c&u����BA9�c&t��Cu�:$u��
�c&�=�c&�u���[�S�\$9�c&w��c&�^&9�r��c&�=���[��9�c&v(vQ���
�c&��c&�P�@��9�c&w�[��9�c&s#s!����c&�P��c&����9�c&r�[�S�t$�J�����
���j������K���u�[�VS�\$1��;t����PC���&ƀ;u��[^��D$��        u�Ð��~��u�ø&�VS�\$�5�^&�s���PC�"���;t9�c&v95�^&t�[^�    S�\$��        uhYK������[Ð����~��u&j^�G������?��t��@P�0�����[Ð��S���(b&9�c&t��c&HP�N�����1��j�������1����c&9�c&t��c&@P������1��j�������1��S��c&������Å�|9��c&9�c&tS��c&@P����_���1���u"S�5(b&���_����uj�p�����1�[ÐP������1�[�j
                   22323: �Q������������c&�
                   22324: ��c&����hT_&�B��1���5xQ&�1��1����W&���P���1�á�W&��P���1��WS�|$��T_&r9=xQ&sj�������[_Ð�=�W&�5(b&���������7�5(b&����_���(b&��c&0��?����������H(b&��c&��c&��Q&�*9�c&v�5�c&������[_ÐS�
                   22325: ��[_ËD$��W&����W&P���������D$�(b&9�c&t
                   22326: P�@������P�������
                   22327: I-search: ��&WVS������t$�D$�������}h�M�Z�����W��������=������������}1�[^_��&Ð��ȃ���Q&�����t=�MtT=�Ft�=TEuZ�ȈF���|:W�5(b&�
                   22328: &���Å�|%��(b&��)�&Ѐ|$^u&HP�i������Y����SW�9�����G�������
�W&�X&�W&��}
                   22329: j��&��1�[^_��&�UWVS�t$�l$�=�W&�\V�7����Å�|K��}
                   22330: j
                   22331: ������W���������(b&0������������ЍD��>^u&HP��������[^_]Ð������T_&s�j�Z������xQ&��W&�����[^_]�WS�\$�D$�8^u1�P&0�������������HPRS衾�_������%���[_Ð��PS赾�_����t)�[_Ð�����[_�VS��c&���c&+(b&�5(b&�������Ƌ(b&��c&S�l���(b&��c&��c&��c&��Q&&��c&���W&V�C��1�[^��5�c&������1���5(b&������1��j��   ��1��VS�\$��^&���uj
                   22332: ����j
�
����������(b&9�c&u!�5_&�`������5_&��������c&��c&����Q&)‰�^&��Q&��5�c&��������(b&9�c&u��c&9�c&v��Q&������c&9�c&v1�������c&+�c&��)�1���j �I�����C9�}��Q&���9�c&|� ��c&9�c&v�>�(b&9�c&v�*��(b&9�c&v�<V����������t���j�������K���u���c&9�c&s��K�P������9�c&r���^&&[^��
(b&9
�c&uj������1��
�c&9
�c&un��c&+(b&��&tԡ�c&�@�P�#�������c&�@�P��������c&�@�P��������c&�@�P��������c&�P��H��H��P��X�����c&�@�P���������c&�P�p�������c&�@�P�^�������c&�P���H����c&�P������1���X&����1���X&&�&��X&�&�S��c&+�c&��c&��c&��Q&&S���S������1�[�VS�\$h�W&�C&P�l�����S�5�c&V�&��_���3�X&�<��W&th�W&�4��W&�K����X&�4��W&�X&@�����X&[^�
                   22333: nothing to yank�=X&u�X&�����X&�X&�
X&�X&�<��W&t��c&��W&�4��W&�g�����1�ÐhT�������j�� �����1��
                   22334: yank something first��WS�=�W&Tt+�=�W&�Tth�T������j��������1�[_���0ҡX&�<��W&������������K��c&)�P������S�5��������=X&u�X&�  ����
X&�X&�<��W&t��4��W&������1�[_����(b&��c&��c&��c&��c&��Q&&���j�E�����1���t$�������(b&��c&��c&��c&��c&��Q&&�j��������1��1��VS�T$�Ѐ:t6����8^u#@�8>~��B��8?t��������^BH����B@�8u��[^��D$��~��u"��W&^��W&�?��t�€�@��W&�
����W&��W&�&��W&�%s%s = %s
                   22335: '%s'
                   22336: VS�\$�t$��&u�5�Q&������PhlV������u�5�Q&�m�����PhlV�s���V�V�����PhoV�\���������       ���Q&��8�Et�phuV�-���[^Ð�����Q&�4hyV��cannot bind, not a tty
                   22337: %s: no such function
                   22338: ��UWVS�\$�l$ �D$�=�Q&u
h*W������uG1��1�������  �Q&����t�;TEt�;�Ut
                   22339: VW�������F��~�G��~�[^_]���S������1���Q&����3����      &Ћ��88Su�&�
�8HSu�C�ԅ�uVW�e�����[^_]��Ð��}u
                   22340: �x@��|$$ua�x@�=x@t'���U�s践�_����t���;u�;t�C
                   22341: $tUhBW�����;8Su�5�Q&�;HSu(�5�Q&� ��@U�1�����h�W&U�������D$������    ���Q&��@
                   22342: $t���Q&�<th�W&�4�3���������  ��
�Q&�L$�&�Q&�L$�[^_]���Sh�W&�e���h�W&h�������Q&��&��x@���Jy��&��Q&������ڸ�&���@���y��A��~�x@�=x@t%��Q&f�yt�A�Q  ��      &؉����9u�h�W&h�6�����Q&�&��&�������y�A��~�[�WVS�|$�T$�L$�\$�t$ ��Q&���@���@���@���@���@DŽ��@[^_���c&��W&1��VS�=�W&uj�N�����1�[^Ð���c&9�W&v��W&+�c&�5�c&�����c&+�W&�5�W&V�L�����S������S�f������5�W&1�[^Ã=�W&t��W&��c&��W&P������1�Ð�j������1����./��HUWVS�D$0ҋ|$`����������щ�M�|$\��h�^&�|$`��������щL$�D$�D&�D$�t$�����Ët$\�*[����u��=���t$\�,[����uf�,[f��h,[�t$`S�E��_��P���_���t$`S���_���D$PS�ٱ�_����u<f�T$ f���f��@u
�D$/�(���f���uj&S�5��_����u�D$*�|$t&Eh�^&S�����9- X&}�- X&h�^&�]&S�����t$`h�^&S������V菱�_���|$\t�|$t
�D$�D.��D5�,X&9$X&rN�$X&+(X&��h�^&���D$�t$�5(X&�����(X&����(X&�$X&&É,X&�$X&�0�$X&[^_]��HÃ� UWVS�$X&+(X&���T$(�(X&�D$,�Y&h@�t$,�t$4�}������
 X&��}������ʃ�� X&�t$(N�
�Q&�ș�= X&�É�����A�L$ �D$9L$�����1��D$$j
                   22343: �������D$�D$(9D$���l$���|$t,9t$$~&���j  ����������}�N���4�9t$$݋T$,���3�W�������\$0ɋ|$����������щL$�t�� X&&T$$h�^&�t$�����l$ �D$ &D$9l$(�k����D$�T$ 9T$�)���h�^&�t$0����j�������[^_]�� �j&���1��j�&��1��j&�I��1��j�9��1��j&�}��1��j�m��1��j�   ��1��S�\$��c&�&H9(b&t�8 t�8        u�9(b&uj/P轮�_����uS�l��[Ð��S�
                   22344: ��[� ��\UWVS�D$�����D$��$h&��c&9(b&tK�; t�;   u�C���a&$t
�{&<t�{&>u&C�;<t��;>t���$pt)���P��c&�u�������c&�8t
                   22345: �8 t�8        uڃ�$p&t6� X&h�^&j@������(X&�$X&��@�,X&�        �����CF�;t
                   22346: �; t�;        u��j ��$l&S�u�����VS豭�_��h�^&V����j/S���_���Ņ�t�E�,[9�t�؉D$ �
                   22347: ���D$ *[�t$ ����_���D$�|$uj������[^_]��\Å�u��$h&����E0�������������H�D$�\$d���t$�ϩ�_�������p
                   22348: �x
                   22349: .u�xt݀x.u�xt��t$VU���_����u���$ptD�|$�u"VS迬�_��0�������������H�D$���D$&VS�e���D$�Dd��$p&�c���V�t$$�������Q�����t$藠�_����$p���|$�����u��$p������T$�tdV��������|$����$h&9�uƄ$h&�0����$i&9�uƄ$i&Ƅ$h&/����h,[Q赫�_���D$dP��$l&S蠫�_���D$$PS�j��_����uf�D$,f%�f=@uh,[��hk_�:�������$pt��$pu�|$t�g���[^_]��\Á�UWVS��$ &�=�c&9=(b&tO�? t�?      u�G��$(t)���P��c&�U�������c&�8t
                   22350: �8 t�8        uڃ�$(&t6� X&h�^&j@�ҽ���(X&�$X&��@�,X&�        �����GC�?t
                   22351: �? t�?        u��0���$ &����������H�D$������D$h_&������T$�T$����ƅ����$t�^0������������Ѝx�9|$��t$S��$(&P�m��_����u���$(t4���uS�t$�
��_��������D$&S�t$�������D,��$(&�j����FPj��������W��������$(tx��|u ��$(tj�W�����[^_]��Ð�T$�\S�6������|$uhk_�"���������$(u�]�����$(t��$(u�|$t�=���[^_]���S�\$�L$�؊A8u��t��@�A8u��u�)�[ËD$����У�c&x       �=�c&  ~��c&&j������1��WVS��W&���=T_&r9xQ&sj�g�����[^_Ë�=�W&etV0������������Ѝt�9�v%���> t�>     uN9�w�����N9�v
                   22352: �> t�>        u�> t�>       u&FV�������x����ր>t9��> t�>        u.F�>u��&��F�>t�> t�>       u��
���> t�>   uF�>u��c&�
�c&��&͉��&F�>t
                   22353: �> t�>        u���R�������1�[^_�VS�t$��c&9�c&uj�e�����1�[^Ð��_�=�W&e����c&&����9�c&����   `��C9�c&����Bu�;$u�9�c&����Lu ��  `�P$&������9�ul�n���� `�P$th����9�uP�    `�R���      `�Pu�;$uM��Uu �P$t8��%�9�u�  `�� ����P$&t����9�t���   �     `�&�C9�c&u��
�c&�=�c&�� ���S������1�[^�VS�=�Q&u21���c&�����P�3�����&�C9�c&v95�^&��c&��Q&&��c&[^�$Id: vi.c,v 1.3 1992/08/10 12:03:31 sjg Exp $VS�t$�\$��[&j��͢��@��[&��[&��[&&��[&��Z&��[&a��[&&��[&&SV���[^�/?VS�\$�=�[&    t-��
t��
                   22354: u#j
������j
                   22355: �����������&[^Ð��
                   22356: 9�[&�G��[&�$��h��� i�j�j$k�k,m,m,m4j�k�k�=�[&t_��u��[&�^S������tj�����"&���=�[&u�|Y&�H�&���=�[&��%�P�����\X&�`X&�Cσ�w��Љ`X&��[&&�p�0X&�\X&&S������[&�=�[&     �E�T�|Y&�@�@��/u$jj&h�h�^�����w�����[^Ð��jj&h�h�ڐ���Q&$ t"�|Y&�B@P�r���j�y�������|Y&�H�P�
                   22357: �@j&�d ����[&����      `�X$t�`X&���DCУ`X&�~���\X&��0X&�\X&�����dX&�Cσ�w��ЉdX&��[&1�[^Ð��\X&��0X&�\X&�0X&9������Q&$uw��� `�X$t�dX&���DCУdX&��&���=`X&u�5dX&�����5`X&�5dX&�5`X&�\X&��0X&�\X&�0X&9�tR���Q&$tS� ����[&�&��[&�u&���u��[&�`&�\X&��0X&�\X&��[&�@&��
t#
��
                   22358: t�����������t&����Z&ƀ4X&h4X&h�[&���_��멃=�Z&u�2��[&�F���
�Z&��Z&��4X&~  ��4X&u�|Y&�H�|Y&�H�p�pj�R��1�[^Ð�j�A������Z&�|Y&�@&�@&����=�Z&'uj����봐���Z&��4X&��Z&��~��u�|Y&�H�P�
                   22359: ^�@�H�P��@��|Y&�H�P�
                   22360: �@�|Y&�R������[&��t"���G&�V&�������F&����[&h0X&�5`X&�����t����&�&�����&t7�&���=�[&t
                   22361: ��Z&�=�[&��%�P������j�
����������[&�=`X&t�5`X&�5�[&h�[&�5�[&�!������%���t �n������uyj������j��c���=�[&t;�=�[&st�=�[&ct      �=�[&Cuj&��5�[&������t
                   22362: j�[�����j�Y������[&j�;�����1�[^��T$��ru�
                   22363: Ð���Q&$t�À��Q&}�        Ð���Q&$t�Ã�.u�Ð���Q&u�Ð��VS�\$��������&��t^�u&���t�����_&�����t;�R&���=�[&st�=�[&ct      �=�[&Cu
j����[^á�[&HP�쐐��|Y&�z��&�=�Z&~�
�Z&�J�=�[&�k&�B+BP�B@BP�BBP���_���|Y&�H�@&���|Y&�z�.&��Z&�B+BP�BBP�r�И�_���|Y&�p)p�@�����|Y&�x��j&�j���á|Y&�P+PR�PPR��p��P�y��_���|Y&�P)�)P�@)�9�Z&}��Z&�)�Z&�|Y&�X�~�|Y&�BH9Bu    �����[^Ð��Z&���Y&��Z&�=�[&&u&�B+BP�BBP�B@BP���_���|Y&�@�
|Y&�Q�A��A�=�[&u�q9q~�A1�[^� #��UWVS�\$,1��u!�t$0�>Gu
                   22364: ��[&C���|$0�?_t�&�D$0����Q&$t5j�t$4S�����…����|Y&9Pu��t&J�|Y&�P�����Q&$uZ��Y&�5|Y&�t$�>�:�v�D$ �p�r���_����Y&�5|Y&�~�z�F�B��[&j�t$4h�[&�ߖ�_���t$0���Ѓ�l�(�$� r��s@}@}@}@}@}@}@}@}@}@}@}@}@}@}@}@}�z@}@}@}@}@}@}{hv@}�v@}6x@}@}@}@}@}@}@}@}@}@}@}@}@}{@},x@}�s@}�u�u@}@}v@}Lv@}@}@}@}Rx@}�u@}w@}@}@}@}@}�w@}@}@}@}@}@}�x@}�s@}0t0t@}@}@}@}<vhv�v@}@}Rx@}$u@}�v w@}x@}@}`w0t@}@}@}@}Dz���b      ����[&&�|Y&�zt(�B�#���[&&jj�E���=|Y&�G�G��[&&�  ����t$0�8F&u1ۡ|Y&�P����D$0�x&���Q&$�&j&�D$4@PS�����…����t$0�>cu7�~&wt�~&Wu+�|Y&�X�@��
      `�A$u��J��A$u�B�
|Y&9Q}�Y�����ӋQ�|$0�?ct9�tRS�T$��
���T$�D$0�8ytRS�P���|Y&�X�t$0�>c�$�&�����[&&�|Y&�zt�B���j�5�[&h�Z&�����uK���|Y&�zt�J���������[^_]�����[&&��j�5�[&h�Z&������u�K������[&&�|Y&�p�p�&���|Y&�p�p�����|Y&�p�p�e���|Y&�z�>�J�6��KS�5�[&�'�����Q�����[&��[&������[&&��������[&&�|Y&�@��������[&P�5�[&�������������[&&�[&���[&)�P�5�[&������������[&)�[&�q��
|Y&�y�������[&&�Q�I�L$�t$0�F&��=���[&&��[&�#����|Y&�z�E�����[&&��B9B}�Z+Z��BP�r��
�������|Y&�z������[&&��B9B}�Z+Z��BP�r����|Y&��BP�r�
�����|Y&�z�������[&&9Z}�Z�r�B)�P��
                   22365: ���|Y&�p�@)�P�V
���|Y&)X�2���=|Y&��Y&�|Y&�=�Y&����[&�����&��Z&�t$0�>�=\R&�=\R& �����=\R&?���؋t$0�>Nu��4&��h�[&S�5�[&�5�[&�Q���…�}���������
                   22366: j�,��������[&��[&�s���j��5�����������:������
        `��A$u�:
                   22367: uB�:u�:�_���KtP�
       `����B�:�G�����A$u�:
                   22368: u�:�/�������A$u�:
                   22369: uB�:u�:����Ku��:�������B����1ɀ}t4�=      `�|$��Ƌ|$�w$u�:
                   22370: u�&���t1ɉ�B�:u։���[&&�
|Y&�yt�A�:t$��
 `�
���CB�:t��A$u�:
                   22371: u�jj&h#q�h
                   22372: ����ujSU�X
                   22373: ����t�������������|Y&�z�9����J�1����|Y&�z�!����ZZ��    `�J$t��[&&�����9�u.�       `�#��J$&t!��[&&�����9�u        �     `�&��|Y&�BH9B�}�B�u��|Y&�@jj&h%q�      ����������&[^_]��Ð��D$$��Y&�h�|Y&�B�J�&�        `�C$�D����L$�|$�~!�щ��L$�|$�~�A�|$�4�r$t��D$�|Y&�r�t$9r~4�z�>�D$�
   `�t$����D$�|$9z~�B�4�q$t�\$+\$S�|$�5|Y&~�|$ �t$ U���_���|�*t�+*�D&��+U����É\$ U�3���_����u�{u�D$$�����|Y&�p�pU迌�_���|$$}
�D$$[^_]���D$0�8=u_�5hb&j
                   22374: �B��_��j�t$$�7���5hb&趇�_���|Y&�zt�B���[&&��[&1�[^_]��Ð�t$�t$����t$�=|Y&�w���j��D$ �T$ ��0�����������JR�t$$����D$��u���;tjj&h#q�h����t��D$$������[&&��[&&j�
���|$$������=�[&u�|Y&�zt�B9B|�J1�[^_]�����UWVS�t$�l$$�D$1ۋ|$ ���иo9��e�$��}������������������������������������������������������������������������������������ �������H����d�������������������������u�|Y&�x��V�/�&����u�|Y&�x�kV���&����u�|Y&�B@9B�GV�{�����x���u�|Y&�B@9B�V�������P��L$ �9�=XR&�y&�=�[&�=XR& ��&�D$�=XR&ft        �=XR&Fu�D$&�=XR&a���ЋL$ �9,u��4&���t$RV�5�[&�T$$�(���ËT$����&����&����&�&����u�|Y&�x�[&�|Y&�X)���&1��&����u�|Y&�B@9B�+&�|Y&�x�b&��X9X�T&�XK�K&�����u�|Y&�B@9B��V������u�|Y&�B@9B��V�������&&�1ۋ-|Y&�uN9����E��   `�B$���C9����E��B$u���|Y&�x�����X���|Y&�X9X~)����@�P�&���D$�|$uC�|Y&9Xڡ|Y&9Xt�&����|$~C�|Y&9X�����[^_]��ÐKx�|Y&�@�P�����9T$uF���D$��9�u&N��u���t&C��[^_]���S�\$�1��=�[&��%�P�5�Z&h�Y&��&����t     �����[Ð���K��ɡ|Y&�x~�H��[&1�[��T$�D$)У�[&tP�|Y&P��Ph�Z&�        ��_����D$��[t/
��(t ��)t3�I���{t#  ��]t,�:����}t+�1��&Ð��Ð��Ð������Ð������Ð������Ð�1���|Y&�p�ph�\&苅�_���|Y&�@��]&��]&ƀ�\&��|Y&�@��]&�P�5�]&h�\&�p�D��_��ËD$�T$�|Y&hY&�lY&�pY&��Y&DR&�LR&�PR&�tY&�TR&�xY&�DR&�hY&�5_&蔸������[&��[&��Q&+�[&�����[&j
虶�����)����5_&���������\&��\& ��\&&�VS�\$��u1�[^Ð�|$t)�|Y&��J�BH9�|
                   22375: �����[^Ð�9J}A�J�<���
|Y&��Q�AH9�}׋A+AP�AAP��AAP�&��_���|Y&&XS�t$�|Y&�pp��P�ރ�_���|Y&&X1�[^�S1ҋ
|Y&9Q~"�A��     `�
B9Q~�A��C$u�Rj���[�VS�t$�\$�|Y&9Zt�B)�P��BP��BP�`��_���|Y&��)�)B[^�WVS�|$�L$�t$�|Y&�xt�PI���t-�����tB9Su
�����[^_ÐJx�C�9�u�I���u؃|$u
                   22376: ��tJ���B��[^_�UWVS�|$�|Y&�H9H��O������Ëk�5  `���)�Fu�<)_u ��S�����Fu�:_u2BA9K��)��F$u!��S��Fu�:_t�F$uBA9K�S���F$tA9K�9K~O���u���[^_]�UWVS�|$�|Y&�H��~tO���tn�ŋ5     `��I��~_�]��V$u��Vu�<_uIx7������Fu�:_u#JIy��Ix�E�&�Vu
�<&_t�V$t�A��~O���u���[^_]���UWVS�l$�|Y&�P9P��M������Ƌ^K�\$�=     `��B9T$~n�^�\$��O$u�FH9�}T�Ou�<_u'B9V~A��L$����&�Gu�9_u*AB9V��!�B9V~�F��Ou
�<_t�O$t�J9V~M���u���[^_]���UWVS�t$�|Y&�P9P~CN���t=���i�=     `���*�G$uB9Q�Y��G$tB9Q�9Q~N���uЉ�[^_]�VS�L$�|Y&�P��~>I���t8�Ƌ       `Jx"�F��C$u�Jx�F��C$t�B��~I���uЉ�[^�WVS�\$�|Y&�P�pN9�}LK���tF�����5  `�B9�}6�A��F$u�AH9�} �B9Q~�A��F$t�J9�}K���uʼn�[^_�grabhist: bad history array
                   22377: ��WS�T$��|89�[&|0u
����1�[_���R袁��芁���uh!�躚�������[_��Ã|$t�����|Y&�D$0҉߈�����������J�D$�PRS�D$�p��_���|Y&�@1�[_���UWVS�|$�t$�l$ ��u��t��[&H9�|��&u
�����[^_]Ð��UVW�0����Å�u'��tޅ�t�Uh�\&�ԃ�_����|��,���1�[^_]Ð���t��|$t������|Y&0�������������H�BPS�r�[~�_���|Y&�@�k�[^_]�j
�-�����j
                   22378: �#�����賯���5_&脭������[&��[&��\& �S�\$��}��\&�       �����\&�Y��t�S��\&����)Ѝ���[&P�&+�\&����)Ѝ���[&P�U&���&+
�\&�
�\&[�S�|Y&�9H}�&[�1ҋ9X~&���R�|Y&�@�PC�����¡|Y&9X�9�[&|1�[Ð�&[���UWVS1��D$1�1��D$1��|Y&9h~m�����+T$��[&���[&��9�~�l$�|$�\$�t$V�|Y&�@�PC�V���ơ|Y&9X���W�|Y&�@�DPE�/���lj�)���[&���[&��9�Ρ|Y&�([^_]����T$�D$��~��u��     u@Ð���@���UWVS�|$$�D$1ۡ|Y&��D$�t$�L$9
�[&��9P�����9Pu��t��
�[&�L$�|Y&�@�<~�<u;�< u�� FC9�[&~.��$u��&����^FC9�[&~�|Y&�@�4@���FC�|Y&9Pu��u��
�[&�L$�L$B9�[&~�|Y&9P�`����|Y&9Pu��
�[&�L$9�[&~~� FC9�[&����D$� ��[&�t$�l$ �=�[&�4����8Mt'9�[&t
�t$S����P��������[&FECO���uɡ|Y&�8~�|$t�+��8~�<����� �|$t�>8�\&t-�t$��Q&���P�?����P臬������[&��\&�L$9
�[&t�t$�t$���[^_]���VS�t$�\$95�[&���V&��[&)�9�}Xj
�)�����蹫���5_&芩�����
�[&�
�[&��[&��[&9�}x�PC��������[&��[&9�|��Z����[&�
�[&9�~I�j���������[&�
�[&9���-���[&+�[&&����PC蒫������[&��[&9�|�5�[&[^�S�\$�D$=&v�&PS�����������S���tP��������u
�␐������[Ð�|Y&9Xt�p�pS�"y�_���|Y&�@�
                   22379: �|Y&�@�@[���j&�D$P�5tQ&��z�_����&u�D$$<t<����������h&j�|Y&�p��x�_���|Y&��@�@�@h&j��Y&�p�x�_����Y&��@�@�@j�߫����j�]7���D$��������T$�$�D$j&�D$P�n������$Id: tree.c,v 1.2 1992/04/25 08:33:28 sjg Exp $%S (%T)%T| %T%;||&&%s %Tfor %s in do %T%;done case %S in%;(%S%c %T;;%;esac if %Tthen %Telse %Tfi whileuntil%;do %T{%;%T%;} %T&function %s %Ttime %T<botch>UWVS�|$�l$���o�J�9��0�$���0�������ؒؒ��|����������Ԕ����|��_�;t�3��h��U�����;u�_�;���3��h��U����;u�������@����wh��o����wh�U�~�����������wh
                   22380: �U�b��h
�U�T����������wh
                   22381: �U�:���w���?u��Ph���&���wh�U�
                   22382: ���t?h$�U�����_�;t����3��h��U�����;u�h
�U�����wh(�U���h.��&����wh6�U����w��tghC�U����^�;t9���3hE�U�g���)�{t�|PhH�U�H�����;u��vhK�U�/���v��u�hS��&����whY�U�
                   22383: ��h
�U������t�wh_�U����h
�U�����t�whg�U���h
�U���ho�����w�y��?u�s�Ph�U����wh�U�q��h.��X����wh��U�V��h���=�wh���"���w�wh��U�/���$���wh��U�����h��U�       ���_��t�;t���3��U�5���;u�[^_]�< <<- << '>> >! > <&>&%s %s' WVS�\$�|$�w�?&~���0PhH�S��������P��9����$����ĕ�2�̕���h@��^���$ t
                   22384: hC�����hH�S�9����$uBhL��2�hN��*���$@t
                   22385: hR�����hV����?uhY��h\�S��&��������u(��$t�wh_�S��&��[^_Ð�whc��萐�wh����S�\$�T$��t'�J9Jr��%�PR��i�_���!�B��B����
�]&x
��]&���]&��[�VS�\$�t$��`u-V�^��}�$P������V�؃�@P�{�����[^Ð�؃���uV�^��}�$P�U�����Vj?�͐VS��WVS�\$�t$1�����C�9�r��$�L��×l���������ؗ��uSVj\��������F����&Vj"����1�Vj"�w�Vj$�������Vj{�VR��������C��u�;�u���V�PC��������b�����Vj}�1���Vj$������Vj(�}�������V�PC�������;u�Vj)�]����������[^_ÍD$P�t$�t$�F��1��S�D$�L$�T$�\$��]&��]&RQj���jj������1�[�; 
                   22386: UWVS�l$�|$������%��&�U�Z�E�:9���&�$������P�����������������������������������������������ܙ<������������������������������������������������������������������t$���w�������_��;����t$�PC�������;u������t$�w��=�������G�1���du����j
                   22387: ��t��P�ds�����Å�tK�-�;tk���t$�PC�>������;u��Q�t$���w��m����=����s��|$u�p��;t'���t$�PC��������;u��
�t$R��������UE�������[^_]�UWVS�|$��u1�[^_]Ð�t$j�U����ŋ�U�t�t$�w�&���1��E�u �E�Q�_������u��t$��+G$�P�����E�Ƌ_�;t���t$�3���������;u���u �E�Q�_������u��t$��+G$�P袅���E�Ƌ_�;t���t$�3���Z������;u���t�t$�w�����1��E�t$�w��������E�t$�w��������E��[^_]�WVS�t$�|$jV�%����)�WS������SVW�l�_����[^_�VS�T$�t$1��
                   22388: B�9�r��$�D���t�t���0�0�d�x�C����B��u��:t�B빐��u��u��[^Ð�K륐�B��u�뛐����UWVS�\$�ݐ���E����u��t$ ��)�$�P�R������D$�;tY�߉l$���7�t$ j�+����ËT$����V�S�V�S�~t�t$ �v��������C���D$�D$�?u��T$�D���[^_]���WVS�t$�|$�����~tW�v�ƅ���~t(�^�;t�W�3謅�����;u�W�v蘅���~t*�^�;t���W�3�|������;u�W�v�h����~tW�v�*��W�v�b�����W�v�V�����WV�4���[^_�WVS�|$�t$�����{tW�s�
���WS���������u�[^_�$Id: exec.c,v 1.4 1992/08/10 12:02:38 sjg Exp $%s: %s
                   22389: ��UWVS�|$ �D$��u
1�[^_]��Ð���D$$$ t$�D$$$&u�?t�t$$W����[^_]��Ð�j�el�����$b&��t�p)�u�?uOh�^&j�!�����^&1Ґ����^&f�PB��    ~�D$$$t
                   22390: ��^&f����D$$$t��^&f�@���t�_�;t�3�������;u�J�9��
�$�p���������4�\�\���s���D�ܢܢD�s���H���(�8���^&�t$$j&�w�X���Pj �w�J���PW����D$�w�D$$ P�w�i������&��D$$ �D$$�D$$$��D$$j轄����^&f�j&誄����^&f�B�D$$�D$$j��^&�P��b�_���?uV�\$���S�2���j&�t$�b�_���t$$�w���j�t$�b�_��S�:����D$$�D$$��?t��D$$$��D$$j&��^&�@P�Vb�_���t$$W����j��^&�P�6b�_���D$$$�b��D$�a&�Oj�w�F�������?t�jW�3��������D$$"P�w������j�w�������D$����D$�����Ѓ?��%�9���j�w������y�����^&�tj&�w�n�����������^&�X���h�^&��^�_���…�t
��&��␐�;�r����3���w��l��P�p��j�w�M������D$�;u��;��^&�tj&�w�ބ����������^&�X���h�^&�N^�_���…�t
��&��&�␐h��j��j�_��1퐐�US�%���Ń�&��&U�w�&l��P��o��j�w�������D$�Ð����^&��h�^&��]�_���…�t
��&�o&�␐j�w�b����������Ѓ?��%�9��C&j@�w�:������D$�Ő��%&j�w��������u
j�G�p����j�G�p��������j�w�"����ŋ�����?����_�;t(j�3������ƅ�tVU��k������u ���;u؋�����?t�����j�w�~����&j�w�r�����w�w�A�
����t$$W�/���D$�L��G�0�s��S�w�w�_�_���=< `u
                   22391: SW����5< `��i�_��PVhl�����g���=�^&t�5db&�_�_���5hb&�_�_���D$$$&t�t$�"_�_���D$[^_]���_:%s: not builtin
                   22392: %s: undefined function
                   22393: %s: not found
                   22394: %s: cannot execute
                   22395: ��UWVS�t$ �|$$�D$�=d&t
                   22396: WV�������t0�?t+������8u��p�jhh���pp��P�Sm��h�^&j8�{���D$�
�^&�H4��^&�h���u����d&PS����ŋE����
                   22397: ��&tJ�S���_&�E�������t5S�w��PShb&�Nx���Ņ�uSh���~���} �t}�u%���?u��^&��&���L$(&�P�����f�Ef%t
�T$�J4�
�^&f�Ef%��%��؉Á��>t��jS�6���Go���>u�W�E�Ѓ��x&��E$uShѤ�j}���T$�z1��&C�����u�K�L$�Y�1U�>tjh�6����n���>u���^&h�^&�Y�_����t�a&�T$���j�u�J�������E$u5jS�)Z�_����}
                   22398: Sh����Sh����|���D$&���ujhh���Pn��P�3k���>t���jh�6���+n���>u�D$($&t8��
�=
d&u�D$($u"jh�^&j�?e�_��jh�^&j�.e�_���L$�
xR&�m�-�R&�=lR&�t$(hhR&����D$�|$t�=d&t�t$�Lb�����T$�a&�D$[^_]���EXECSHELL/bin/shNo shell
                   22399: ��&WVS��$&hM��Zf��P�Ei���ƅ�t�>tj&�5�b&V�e���ƅ�u�W��G�O��G��D$j�w��`�_���Å�|%h��D$PS��a�_����~�DS�QY�_���|$#���|$
!���T$�|$����: t�:        uB�:u��:���:
                   22400: t~�G�����B�:tg�:
                   22401: t
                   22402: �: t�:        u�:tS�:
                   22403: tN�B�:tE�: t�:     uB�:u��:t0�:
                   22404: t+�G��G�H��G�P���B�:t�:
                   22405: t
                   22406: �: t�:        u������G�0��$&�w�G�0��Y�_��h_��2z��[^_��&�%s: shcomexec botch
                   22407: VS�t$�6��r��P�6hb&�t���Å�u�6h����y��V�C�Ѓ�[^�UWVS�l$�5�^&��t[���5b&U�r��PU�~W��s���Å�t�$u0�~4u#U�_r��PUW�t������C�v4��u��$&t�5b&�s�s������#��|$t"�5b&�t$�������C�1�[^_]Ð��S�t��1�[^_]�VS�\$��;=uC�S��q��PShb&�s��    0�@&�T$�P[^�UWVS�|$W�q����1�j/W�b�_����t ��]&��]&��]&�����^&��t#��UW�CP�r���ƅ�t�$u�[4��u߅���UWh_&�kr���ƅ�t9j&�v�|U�_����t$�$&t�5_&�v�%w���F���u3UWhb&�r���ƅ�uUWh_&�r�����F��~u_�$uY�|$u��]&��]&��]&j&�5�b&W����Dž�t"��b&���]&u��^&PW��`�����F���[^_]�VS�t$h_&��r�����r�Å�t1�$t��u�C�8/t�$&t�5_&�s�+v�����[^���@WVS�t$P�|$Xj/V��`�_����tWV�4T�_������%���!�[^_��@Ë\$T������b&�;t����C<:twB�;u���b&t�/B���&����1�AB��u�Wh�b&��S�_������u=��&u%�D$Ph�b&�`�_����u"f�D$f%�f=�u��b&[^_��@Ð��K댐�C���]���1�1�[^_��@�%s: illegal >& argument
                   22408: createopen%s: cannot %s
                   22409: WVS�|$������w�?&v�?u
                   22410: ��^&�7�v�����^&f�J�G����t
j$V�z���ƋG���P��9����$�����������Ȯ�jV��Z�_�K��j&V��Z�_���Å�|jjS�Y�_���jh�&V�}S�_����jV�Z�_����G��PV������:�>-u�S�+S�_���(�����a&$t��X�����Vh����t����}$�G������u��RVh#��t��9t�7S�S�_���t      S�R�_���7�t��[^_�rexec:herein error
                   22411: w+��VS�D$�D$h��P�T�_���D$�D$��u
�����[^��Ð�hjj�t$��\�_���|$�&j�[����h�^&�P�_����t%�D$��t�t$�S�_���<[�������[^��Ðj�e������T$�P��`&j�Cv����=&t
h���s��j�5P_&�x����h�^&�pu����^&���^&��u�Z��h���s�S�_���D$�D$��u��Y��hjj�t$�\�_���t$V�S�_���t$�hZ�_���pZ���t$�7S�_��P�R�_�����t$�R�_����[^���+ %s
                   22412: VS�\$�t$hC���r���;t.�3��hE���r���;u������6��hE��r���>u�hI��r��[^�PS3%sRead error
                   22413: REPLYUWVS�l$�=�R&uh�b&j@�/o����R&��]&@�|$ujU�r&����]&h����\��P�_��Ph���
r���5hb&��Q�_����]&1�1�����Ã�������uh�������]&@9�]&&��]&��@��]&h�b&P�5�R&��o����R&��|(�CЃ�       w ��R&��]&���]&���tC�냐����
                   22414: u3�=�]&uj&U���� ����������~/95�]&|'�|���!��������R&��]&���]&�*�������uhI��q���&��R&��]&�Ph���[��P�[_����[^_]�%*d) %-*.*s ��UWVS�l$�|$�&��]&��]&��}t7���:0���������щ�K��9
�]&~�
�]&�
�]&��]&���:uˋ�]&��]&&��       ~����]&�ؾ
                   22415: ����Ã�     �=�]&��]&&��]&��]&�c���5�]&5�]&���t$��Q&�Й�����
�]&��]&�Й���É�]&��t��]&�5�]&95�]&~�
�]&��]&&1�9�]&~g�1�9=�]&~F������]&�9�]&~'�t��5�]&�5�]&�B&P�5�]&hk��\o��G9=�]&�hI��Fo��C9�]&���]&[^_]�����Sj&�D$Pj�U�_����t   ���t�����&u�\$�
��������������[���$Id: jobs.c,v 1.5 1992/08/10 12:02:52 sjg Exp $�P�_��]&�4_&� _&�_&&�VS1���R&��t3��f�Cf��u!Fj&�C��P�PR�_��j�C��P�@R�_�����uυ�t
                   22416: j&�W�_����
                   22417: �=
d&t�
d&�[^�job control requires tty
                   22418: �=
d&���=tQ&}�
d&h���m��Ð�8_&Լ�<_&�@_&jh8_&j�V�_���@_&��T&&h�]&h|^&j�`V�_����T&&h�]&h|^&j�BV�_���U&&h�]&h|^&j�$V�_��� U&&jh _&j�iV�_���5�]&�5tQ&�
X�_��Ðjh�^&j��U�_��jh�]&j��U�_����T&jh�]&j�U�_���U&jh�]&j�U�_��� U&�%Tcannot fork - try again
                   22419: /dev/null��UWVS�D$�l$��߉�$&tU�t$������[^_]��Ð���5�R&��t��f�Ff��t+�6��u�h�b&jX�i���Ƌ�R&�f�F�5�R&��$t��]&�V�
                   22420: ����F�F�Ff�n��$t
��R&�V�
                   22421: ���+�F�t$h��j0�F(P�������FWf�F&������&��  ��W��k��G��        ~�1�jh_&j�T�_�����K�_�Dž�}@�=<  `u ����tS�T�_��&��֐��&�͐��}f�Fh���k����t�~��M�_�F�=
d&tG��$uA��$u�V�V������]&�@�F��$u�v�5tQ&��U�_���v�v�S�_���5�]&������^&�=  d&t����$tp�=
d&ugjh�^&j�eS�_��jh�^&j�TS�_���=  d&tjh�^&j�:S�_����$u%jh���O�_����jW�8I�_��W�GH�_���5�R&��t��f�F�6��u��tQ&����jh _&j�<S�_��� d&�
d&�b��&P�t$��������$t0�V�0b&��R&��R&�V��R&�= d&t   V�F��jh _&j��R�_����$u����ujV�)���D$�D$[^_]���j�5�]&����UWVS�l$�&1��=
d&tjh_&j�jR�_��������O����=
d&t�4_&��uh _&�TR�_�   ��j�&���4_&��t�&��R&��t�|$�&f�Cf��&t�f�Cf��u�C$u�{f�C
                   22422: �a�f�Cf��u>�S��u�C������C����t  ��
u
                   22423: ��tf�C
                   22424: �C�������&w�f�Cf��u�C��u�&�[���m������t����K &
�c&�K$&
x^&�[��u�f�Ef��u�
�R&�
�R&�m�-�R&�B��1���R&��R&��t*��f�Cf��&t
                   22425: f�Cf��u9S~ �S��R&���u؀=
d&t%jh _&j��P�_���5�]&�5tQ&�R�_����t�5hb&j
                   22426: ��G�_���1��[^_]��4_&@�4_&Ã�(S�D$Pjj�P�_���D$P�R�_���=
d&tj�D$Pj��S�_������D$P�~S�_���Å�}�=<      `
                   22427: u�4_&[��(Ð���&�D$P�"R�_����R&��t�f�Bf��t9Zt���u�=
d&u�[��(�f�B
                   22428: &�L$�J�D$��u     f�B�(��|$u f�B���D$H%��=�wf�B�L$+L$$�J �L$+L$(�J$�L$�L$�L$�L$ �L$�L$$�L$�L$(jh_&j�]O�_���4_&H�4_&�4_&��}
                   22429: �4_&j�D$Pj�.O�_���=
d&�����[��(��4_&��t�r���1��no current job
                   22430: no such job: %d
                   22431: VS�t$��u�=�R&u
hq��ke������u��R&P����Å�uVh���Ce���=  d&t   S�����=�^&t�5db&�E�_���5hb&�E�_��j&S�������[^�cannot find job
                   22432: kill: %s
                   22433: killpg: %s
                   22434: VS�t$�t$����Å�u
h!��d���{u1V�s�H�_����}j�5<       `�N�_��Ph2��d��[^Ð���t��&uj�C��P�mH�_��V�C��P�^H�_����}�5<   `�\N�_��Ph<��2d��[^�job not job-controlled
                   22435: cannot continue job %%%d
                   22436: WVS�t$�|$����u��R&P����Å�uVh!���c���{u
h��c��f�C&S�f&��j�d����u�s�5tQ&�N�_��j�C��P�G�_����}Vh��ec����t1�[^_�jS������[^_�S��R&��t�f�Cf��t        S�������u�[�S�4_&��t�������R&��t]���f�Cf��u�=     d&uf�C
                   22437: f�Cf��tf�C
                   22438: f��t   S���f�Cf��t
                   22439: f�Cf��uf�Cf�C
                   22440: ���u�[�RunningStopped Done (%d)%sSignal %d - core dumpedHideous job state|%%%-2d%c %5d %-20s %s%s
                   22441: ��@WVS�|$P�t$f�Gf����f��&t �����f����f��t������t�������
|��L$�
���L$�
���L$j(�W��)��4��R&�K�_���ƅ�t
                   22442: VS�K�_���������_Sh��V�K�_����ufj(V�eK�_����V��W����)Ћ��R&��t
                   22443: Ph�����Rh��V��J�_���}h���D$P�K�_���������f�G�G$�����t���R�G(PV�w�O9
�R&t� 9
�R&u�-����+P�wh����`��[^_��@�%s: no such job
                   22444: UWVS�t$1�>%u&F�<9<0}6<+t��t�v��<-t�n��<?t0�f���-�R&���-�R&��j
                   22445: jV��J�_����������R&��tr�~&���f�Cf��tW�C(P�J�_����t�k���u��G���0������������Ѝx���R&��t'���f�Cf��tW�C(PV�J�_����u�k���u܅�uVha��_����[^_]���R&��t��f�Bf��u�&Ë��u�1��1���R&��R&��t��f�Bf��t�zt9J~�J���u�9
�R&~A�
�R&��R&��L$��R&��t ��f�Bf��t9Ju
                   22446: �B$u��Ë��u�1��$Id: trap.c,v 1.3 1992/08/10 12:03:15 sjg Exp $EXITSignal 0HUPHangupINTInterruptQUITQuitILLIllegal instructionTRAPTrace trapABRTAbortUNUSEDUnused signalFPEFloating exceptionKILLKilledUSR1User defined signal 1SEGVMemory faultUSR2User defined signal 2PIPEBroken pipeALRMAlarm clockTERMTerminatedSTKFLTStack faultCHLDChild exitedCONTContinueSTOPStop (signal)TSTPStopTTINStop (tty input)TTOUStop (tty output)IOPossible I/OXCPUCPU time limit exceededXFSZFile size limit exceededVTALRMVirtual time alarmPROFProfile signalWINCHWindow size changedWVS�|$���a&$t@W��G�����ƃ�w W��G������)Ѝ��R&[^_Ð1�[^_Ð���[^_Ð���R&����{tW�s�5F�_����tփ�Ny�1�[^_��T$��)���ǀ�R&&�$b&&��u�=�^&&t    �=�^&u
j&h�^&�Q8�_�jh$_&R��D�_���VS��R&��C��t    S�����Ny��$b&[^�VS�\$�C�s��u
                   22447: �;u�NB���;u�CV�@����[^�VS��R&�=�R&th�b&�5�R&�XZ����R&����C�{t.h8_&h|^&�3�D�_���=8_&&tjh�^&�3��C�_����Ny�[^�S�\$h8_&h|^&S��C�_���<_&�@_&�=8_&&t��)����R&&[�VS��R&��{t�Cjh�^&�3�yC�_����Ny�[^�$Id: c_sh.c,v 1.3 1992/04/25 08:29:52 sjg Exp $1��nothing to shift
                   22448: S�D$��^&�xt�p�3������&9S|�C�����&C)S1�[Ðh����Y���&[�%#3.3o
                   22449: S�D$�P��u(j�E�_����S�}E�_��ShL��?�_�����1����\��B��<v�S�NE�_��1�[�%s: not found
                   22450: VS�D$�X��u1�[^Ð�j�5�b&S�6������ƅ�uSh���.Y��V�=������u
                   22451: �����[^Ð��a&[^�%�D$�����u��P�H�����P�_������bad -u argument
                   22452: missing name
                   22453: %s ��UWVS1ҋ5`b&�&�|$�\���C<rt<et�F�<ut�?���&�6�1��1���a&$t��4��a&C��uh9��T$�VX���T$�;u������t�C<-t�?uhJ��T$�'X���T$j?�7�T$��A�_���ËT$���&��=       d&�&�C&PhX��T$�X���5hb&��7�_��������b&���c&����
                   22454: ���N9NrV�l4�_�����t�F��F����������u�&[^_]��Ð��t<��\u7�N9NrV�)4�_�����t
�F��F����������
                   22455: u%1��t��������
                   22456: t#�t��%���a&|
�ЈC�L�������h�b&�7�T$�A��P�E�����T$�?����1�[^_]���S�\$j�lg�������XP�q;����[�%s: %s
                   22457: trap: bad signal %s
                   22458: UWVS�t$���>u4��R&����{t�s�shl��~V����Oy�1�[^_]Ð��6��������u
                   22459: �.������1�����}-���}&��1������6���R������Å�u�v�ht���U���{th�b&�s��T���C��t00�������������Hth�b&U�2?�����Ch����j&�����1҃�&w
�=   d&����RS����>�`���1�[^_]�S�\$�;tYh8_&h|^&�3�E>�_���=8_&&u�{t6�C&�T$�8_&jh8_&�3�>�_���<_&�@_&[��D$���8t�0�1@�����a&��G<����^&�����&v�=�^&u
j&h�^&�%1�_��5a&�;�����cannot %s
                   22460: VS�t$�~t�v��?�������5��&�-��=�^&u#K�����8bu�&Rh�^&�0�_���;����^&�����&v��6hs��.T��[^�There are stopped jobs
                   22461: S�\$�$V&�=$V&&u(�=
d&t�B�����th����S���&[���^&�C��tP�?�����a&�5a&�:����[�set-w�{�%s: unknown option
                   22462: %c: bad flag
                   22463: ��UWVS�-�^&�

d&�L$�|$���7��u'h������[^_]��Ð��>��1�[^_]��Ð�>-t    �>+���F<-���Ѓ��>u�����d&�d&���>-���>�����>oug�?t��7���T$�0=�����ËT$��u����7h���T$�R���T$��d&��u��t
                   22464: �d&�B���u<��t8�d&�/����<w����c&���Ph���T$�>R���T$F�>�]����=        d&t�d&�7��������
d&9D$t�����?tW������E��U�7�p;��������?u��)���H�EU����P�N���E�ǐ����������u��)1�[^_]���VS1��\$�     ��@�8fu&F�����t.�8-t��'���uP�.<��P��D���jP�����������u�1�[^��D$�p�p�q%���Shell: %8s user %8s system
                   22465: Kids:  ����P�]<�_��h����6�_���4$�U&��Ph���6�_���t$�;&��Ph&��6�_��h
��6�_���t$�&��Ph���v6�_���t$����Ph&��\6�_��1����%8s real %8s system 
                   22466: �� WVS�t$0�\$4�x^&��c&�D$P�;�_����S�v�r������ÍD$P�o;�_��)�P�t��Ph���P���D$+D$�c&P�O��Ph����O���D$+D$ x^&P�*��Ph����O��h���O����[^_�� ���UWVS�|$�^&��)P�������ؾ<����������<����Ǎ�Ǎ���I�&I�&s�������uI�&.I���
                   22467: ����׉ŀ�0���C��~݅�ى�[^_]���1��1��=:=.[=builtin=exec=shift=waitread=eval=trap=break=continue=exit=return=setunsetumasktest=timesulimit#���&���)��+� �4��:���A��G�\�L�L�R���X���_���i��o� �w���|�����T�����������$Id: c_ksh.c,v 1.2 1992/04/25 08:33:28 sjg Exp $%s
                   22468: -rWVS�\$���;u9h_&�gI������$t�rhu��Q3�_�������u�1�[^_Ð���3�y�����uj&���������j&�3���d������;u�1�[^_�HOMEno home directoryPWDsubstitution too long
                   22469: substitution failed
                   22470: OLDPWD%s: bad directory
                   22471: CDPATH��(UWVS��$<�D$,1��D$$�k��u)h���D7��P�/:���Ņ�u
h��dL��h��7���D$(�t$(��9���D$0�|$0TV&u2h&��$<&P�p-�_��P�t$,�:���t$(��9���D$0�{���[�\$4�|$4���\$0��0���������щL$�����������щL$�T$)ʉT$�\$4����������щL$�D
                   22472: �=�v
h��K��U�t$4��5�_���D$�|$u
h0��hK���\$+\$0S�t$4��$@&V�5�_���t$4&�S�@5�_�����0���������щL$�T$�D
                   22473: �PV��4�_��h�^&V�4�����,����}-u*�}&u$hE��5���D$$�t$$�8���ž&�}/t�}.uT�}&/t�}&.uH�}/uB�\$8SU�t$8��8����S�(�_����}ShL��J�#&������&S�&��h_��*5��P�8���Ã|$,��������$8&�|$ �T$8�T$����$8&�D$������D$�C�D$�;t
                   22474: �;:u�;u1��&C�|$ 9|$�����t!�D$�/�D$U�t$��3�_���|$�����l$�t$�t$�t$8��7�����t$�'�_����u�D$,&�|$,u       ���]�����|$,u��u�UhL��vI����t�D$8Phu��I��j��������\$0�|$8�|$0�|$$uhE���3���D$$��t�;tS�t$(�7�������t$$�o<���T$0�:t�t$0�t$,�7���
��t$(�G<��1�[^_]��(�bad -u argument
                   22475: ��UWVS�D$&�D$&�5db&�l$���]C�;������C<nt<et�Z�<rt <ut(�O���D$�C���D$&�7���D$�+�����a&$t��4��a&C��u
hI��&H���;u����}�`�E�8-�i����E�}��|$��&��\��&��S�G�F9���&�$�T������������������������������������������������������������������������������������������������������p�|��������������������������������������������D$������j��
                   22476: �b��
�Z��        �R���J���Њ�<w>��\��G��<w.��\��G�$����N9Nrj\V�"�_�������F�\�F�N9Ns���N9Nr��%�PV�r"�_���    ��F��F�G����������}t*�N9Nrj V�?"�_������F� �F�}������|$t'�N9Nrj
                   22477: V�"�_�������Ԑ���F�
                   22478: �F1�[^_]���%s is unknown
                   22479: %s is a shell builtin
                   22480: %s is a function
                   22481: function %s %T
                   22482: unknown%s is %s
                   22483: %s is the alias '%s'
                   22484: %s is a shell keyword
                   22485: %s is *GOK*
                   22486: 
                   22487: builtin %s
                   22488: *GOK*
                   22489: ��UWVS�D$1�|$���~&vu�D$&���7����&�>-t���&���V�b=��PVh�^&�>���Å�u
jV�������Ã|$��1҅�t�S�9����$������$���P�t���Vh����)�_���&�5&Vh���&�Vh����)�_���sVh���5db&�ڷ���������$�����t�SRVh���)�_����sVh���~)�_������Vh���Vh*���1҅�t�S�9����$����������0�@���(�0�h7��)�_���&�YVh9��:�$�E���t�SRhu���(�_���$u-�&�&��s����Vhu���(�_���
hF��(�_���7�����6�����[^_]���unknown flag -%c
                   22490: typeset -i -x -r -t function %s
                   22491: %s=%s
                   22492: %s: not identifier
                   22493: ��UWVS�|$$1��D$�D$�D$�D$��<rt#       <et� &<tt �&�����
                   22494: &���&�����D$&������>-t  �>+��1���L$����и9����$�d�������������������������������������������D$&�4������,�����&�$����������������Phd��.A��F�>�M�����t�|$-u   ����   \$�D$���7�������?�R&�=�^&���7&�|$u�G��GP�<�����&��$���|$u{�|$ut��uphv��~&�_���$t
h��k&�_��f�f%t
h���U&�_��f�f%&t
h���?&�_��f�f%t
h���)&�_���CPhu��N����|$+t�|$t�D$#9D$u�CPhu��&����|$-t��t@��#9�u8f��t�CPh����%�_������S�-��P�CPh���%�_�������������4�������1�[^_]�����|$t.���&��t$U�7�41����u�7h���m?�����?u�1�[^_]���-d%s='%s'
                   22495: cannot alias keyword
                   22496: ��UWVS�D$�^&�D$�l$���}t%�u�������u�D$�`&���}uG�t$��:�����#����{u�$t�s�CPh���$�_�������u׃}����]j=S�(�_���ƅ�uLS�f7��PS�t$�8���Å�t#�{u�$t�s�CPh���:$�_���q��D$&�f���FS�7��PS�t$��8���Ã{u
h���>���$&th�b&�s�=���#��Ch�b&V�q'�����C����}�/����D$[^_]�����UWVS��^&�T$���:ts����������uY��`&�O�2�T$�a6��P�T$�2U�7���ËT$��t'�{u!�$&th�b&�s�T$�[<���T$�#����:u�1�[^_]���S�&�\$��3�������%����;u�[�����1��bgJob control not enabled
                   22497: %UWVS�l$�u�$��������؀=
d&u
h'��<��S�E��u�@�P�������P������1�[^_]�Usage: kill [-l] [-signal] {pid|job} ...
                   22498: -l%2d %8s %s
                   22499: %s: %s
                   22500: bad signal %s
                   22501: invalid argument
                   22502: ��UWVS��D$�D$�T$ ���T$�:u
h����;���T$�2��������J&��R&1퐃;t�s�s�3h���!�_��E����~�1�[^_]��Ð���;-uw�|$up�T$�ztf�C&��a&$t(j
                   22503: j�C&P��%�_�������D$&��U�g��s&V�������Å�uVh���#;���+�D$&���D$���a&$u�;-uN�C&��a&$t@Uj
                   22504: jS�i%�_��P���_����}N�5<   `��$�_��PSh����:���D$�+���;%uUS�������P���������h���:���D$�T$���������D$[^_]���VS1��\$�
���x&mu�&�����t�8-t�;ujjj�gm�����;t+���j=�3�$�_����t�@VP�3�?m�������;u�1�[^�cdprintgetopts=typeset=export=readonlywhence=aliasunaliashashletfcjobskillfgbind)�h�,�\�2�@�:���C���K���U�P�\���c�X�k�|�p���t��&w��|����D�$�D�����$Id: c_test.c,v 1.2 1992/04/25 08:33:28 sjg Exp $-r-w-x-f-d-c-b-p-u-g-k-s-t-z-n-U-G-L-S=!=-eq-ne-ge-gt-le-lt-nt-ot-ef!-a-o()N�&&Q�&T�&W�&Z�&]�&`�&c�&f�&i�&l�&o�&r�&u�&x�&{�#&~�$&��&��"&��    ��
                   22505: ������
���������� ��!����������[][: missing ]
                   22506: unknown operandWVS�\$�ڃ���c&�3�������u8�;t
                   22507: �����;u�����3�������t
h����6���1ۡ�c&�8t�0�    ��P�����u�&��c&�8t ��c&��c&�8th���0�$����[^_�test: %s: %s
                   22508: test: %s
                   22509: �D$�T$��t�8tRPh���/6��Ð��Rh���6���VS�t$�a���ƃ�c&��c&�0�M����u51ۃ�c&��c&�0�0��P��������u��t�&��[^Ð���c&���[^�VS�t$�a���ƃ�c&��c&�0������u51ۃ�c&��c&�0����P��������t�����؉�[^Ð����c&���[^ËD$��tP�]��Ð��c&��c&�0�q��P�����������%��argument expectedclosing paren expected0��WVS�\$��uh�j�n�������uV��c&��c&�0����P�~������Ã�c&��c&�0������th,�j��������[^_��Ð��=_&���_&f�z&����c&��c&�8u��th��2���������t<�������tW��%����c&�0�b������d&[^_��Ð0ҡ�c&�8����������щ�H��%��D$�D$[^_��Ð0ҡ�c&�8����������щ�H���ΐ����c&����a&$ujhC����[^_��Ð�S��c&�0�吐��c&���c&��c&�0����=_&��5_&f�~�        ��c&��c&�8��uh��6������f�Ff����и9���&�$�H���������4�\�������������������������WS�]�_������%�[^_��ÐWS�A�_������%�[^_��ÐS�����W���9���%�[^_��Ð��S�����W���9���%�[^_��Ð��S�n����W�c��9���%�[^_��Ð��S�F����W�;��9���%�[^_��Ð��S�����W���9���%�[^_��Ð��S��
                   22510: ����W��
                   22511: ��9���%�[^_��Ð��WS�&��[^_��Ð��WS�A��[^_��Ð��WS���[^_��Ð����c&�0�������������H��%�[^_�����@S�L$H�T$LJ�#9���$�\��������@�p���h�h�h�h�h�h�h�h�h�h�h�h�h�h�h�h��h��������D��h�h�h�8�����jQ�t
�_������%�[��@Ð�j��j&��1ۍD$PQ��_����uf�D$f%�f=����؉�[��@Ð�1ۍD$PQ��_����u�f�D$f%�f=@���ΐ�1ۍD$PQ�c�_����u�f�D$f%�f= ��릐�1ۍD$PQ�;�_����u�f�D$f%�f=`���{������1ۍD$PQ��_�����c���f�D$f%�f=���K������1ۍD$PQ���_�����3���f�D$f%���������1ۍD$PQ��_��������f�D$f%����������1ۍD$PQ��_���������f�D$f%����������1ۍD$PQ�[�_����������|$���������Q������P�!�_��[��@Ð1ۍD$PQ��_�����o�����_f9D$���Z�����1ۍD$PQ���_�����C�����_f9D$���.�����1ۍD$PQ�{�_��������f�D$f%�f=�����������1ۍD$PQ��_���������f�D$f%�f=������������&[��@�VS�t$�����u!�_&1�[^Ð��_&�C[^Ð���=��t����3V�X�_����tՃ��;u��_&�[^���S1ۍD$DP��$����_����u&�D$P��$����_����u�T$,9T$l���؉�[�Ā���S1ۍD$DP��$���_����u&�D$P��$��v�_����u�T$,9T$l���؉�[�Ā���S1ۍD$DP��$��:�_����u2�D$P��$��"�_����uf�T$f9T$Du�T$9T$H���؉�[�Ā�$Id: do_ulimit.c,v 1.3 1992/08/10 12:02:23 sjg Exp $ulimitUsage: %s [-cdmstf] [limit]
                   22512: unlimited
                   22513: %ld
                   22514: bad ulimit
                   22515: ��UWVS�\$$�D$�D$�&�����;-���S&�B���w�D$�� ��9����$������4�,�4�4�4�4�4�4��4�4�4�4�4�� ���?���7���/���'��D$&1���&��h�h ���*���\$(��t31�������tBЅ����C��/~��9~���������l$UW���_����uy��t)���D$�D$�|$u�D$UW��_����uQ�D����|$t �t$�����t$�����uh=��V*�������|$PhH��>*��1�[^_]��ÐhM��*��[^_]���$Id: getopts.c,v 1.3 1992/08/10 12:02:41 sjg Exp $--illegal option -- %s%c
                   22516: option requires an argument -- UWVS�l$�\$�=^&&u?9-^&},�^&���8-u�x&t�ƿW�����u�^&�����[^_]Ð�^&���^&�4��:tV�t$ ��_����uQVhZ�hm��)���^&�^&���^&�<u�^&�^&&�^&�?[^_]Ð@�8:uf�^&�^&��x&t�^&@��/����^&9-^&|Vhs�hm��(��떐�^&���^&�^&�^&&�4��^&�^&���^&�<u�^&&�^&�^&��[^_]��^&&�^&&�missing arguments
                   22517: OPTINDOPTARG��WVS�\$���3��t    ���;��u
h��'���&�{t
�C���B�8u���&~VSR�(���^&�Z��8u�B4�P�@���R��VP�B&P��������Ã=^&&t�5^&h0��
                   22518: ��P������u
�&[^_���=^&t�5^&h7�����P����\$f�L$f�L$�D$PW���P���1�[^_���$Id: expr.c,v 1.2 1992/04/25 08:33:28 sjg Exp $%s: %s
                   22519: �t$�5 ^&hx��&���bad expressionS�D$�$^&� ^&��7P�����Ã=(^&t
h���������C[�bad assignmentWVS�h�Éރ=(^&=uU�=b&�$f�f%&t
h���U����������P����É=b&�sV����$t�~u�S�V��[^_�VS�]���E��(^&�V�7�����=P�'���@9F��%��F��u
                   22520: 4&�ƒ�&�V�(^&�����&v���[^�VS����k��5(^&�YS�������P������u�@9C���.��<u�@9C�����u�@9C�����>u�@9C���ƒ�&�S�=(^&t��=(^&<t��=(^&>�w����=(^&�j�����[^�VS�i���@��5(^&�&S�+�����IP�����+u�@&C������-u�@)C�=(^&+t��=(^&-t���[^�zero divisorWVS����k�=(^&�A&V������P����Ã�*u
�N�K�N�4��{u
h���H�������/u�F��{�F���%u
                   22521: �F��{�V�=(^&*t��=(^&/t��=(^&%�v�����[^_�missing )VS�=(^&!t  �=(^&-u@�5(^&������P����Ã�!u�{���ƒ�&�S�d�����-u\�[�W���=(^&(u'�N�����Ã=(^&)t#h�&�x����������(^&H��&w
�,^&��
h���N�������[^�VS�5$^&�F��t
                   22522: �� t��        t��I�
$^&���Њ�a&$&tJ��a&����F��%���a&$u�N���5$^&�A
���,^&��(^&&����a&$t^��a&����F��%���a&$u��#t�N����,^&�5$^&P����,^&�&��(^&�\��F��=u��=u
                   22523: ��@�����!u��=u
                   22524: ��,�����<u��=u
                   22525: �������>u��=u
                   22526: �����N�(^&�5$^&[^�h�^&j����b&�^&��@�@�bad numberVS�t$�������C
                   22527: VS�����u7�$t �~t�F�8th�&������������C
                   22528: �C��[^�$Id: history.c,v 1.4 1992/08/12 14:15:33 sjg Exp $ $_argument expected
                   22529: cannot find history
                   22530: can't find history
                   22531: wcannot create temp file %s%3d: %s
                   22532: _${FCEDIT:-/bin/ed} $_rcannot open temp file %s
                   22533: ��$UWVS�D$,�D$(�D$$�D$ �D$�D$1�t$8���>���/&�G<-�$&��������G�
9����$�d&�&@&�&@&@&@&@&�&@&�&@&@&@&�&�D$(�����D$$�����D$�����D$�~����t_���tY�;-u�{&u�D$ �Uh�^&0������������Ѓ�P����D$,S�t$0�
 �_��hO&�t$0���_������hS&�����f&����E�?t����������>��t�G<-u��t߃|$ ���D$�D$�-xQ&����0�j=W�t�_���Å�t�|$�\$��D$�
��W����ŋ>����uȅ�t��T_&s
hg&�B���|$u�uh�b&�/�_������t$�t$�t$�u�����th�b&�����
�b&��b&1�[^_]��$Ã>t7�6������ǃ>t�6�x�����E����|$(t;�5xQ&�3����|$(t�=xQ&����5xQ&��=xQ&�������T_&s�T_&��t��u
h|&�f���|$(t�db&�b�D$$h�^&�B���D$0��^&���^&h�&�L$4�q�u��_���Å�u�T$0�rh�&���hjjS���_�����|$t���W�9�wV�|$$u$��`&�xQ&)����@)�Ph�&S�$��_���uh�&S���_���|$t�������|$t�9�s��|$(t1�[^_]��$ÐS�>��_���L$0�qh�&�v      ��P��
                   22534: ���|$,t�t$,������h�^&�t$0�A���
h�&�����h�&�T$4�r�b��_����u�L$0�qh�&����hjjS���_�����Sh&&h�b&���_����th�b&����
�b&����b&S�o��_��1�[^_]��$��=xQ&T_&v;��`&�P9DV&t+�Hh�b&�xQ&�0�t���xQ&���`&�@�DV&�WVS�t$�>-u
V������!�����a&$tV�e������`&+B����xQ&�t�>?u/�xQ&�����T_&r^F�V�3�X�_����uM�����T_&s��@�xQ&��T_&r2����0���������щ�HPV�3���_���D$��t�����T_&sиT_&9�w9xQ&r��[^_��Ð�1�[^_���substitution too long
                   22535: substitution failed
                   22536: ��UWVS�l$ �D$0ۋ|$$����������щ�H�D$������������ҋ|$$��������щL$)ʋ|$(��������щL$�T
                   22537: ��T$���v
h�        &������b&��b&��t$$U��_���ƅ�tE��)�SUW���_���t$(&�S��_���D$�,0�t$jW�X�_���ǃ|$,u��f&멐�|$t�D$D$PW�F�_����h�   &�2����b&[^_]����_&���`&��T$�xQ&-T_&����|9�|�
xQ&�
_&��`&��T_&�_&��`&���UWVS�l$�t$��tF��NV�����������������t$S��_����uE��tF���NV�q������Y������t
�;t9�t����t$�M�������~1�[^_]����[^_]�����[^_]�S�xQ&�����`&r2h�b&�5T_&�&���T_&���`&s���S������`&r�h�b&�t$�n&�����j
                   22538: P��&�_����t��xQ&[�VS�t$�HV&�=HV&&uOh�&�1&���Å�t<Sh&&h�b&����_����th�b&�C������F�א����b&S�/��_��[^��HISTSIZEWVS�LV&�=LV&&��j
                   22539: jh�&��&��P����P�&�_���ƃ�d���d�xQ&-T_&��9�|���xQ&)����T_&h�&�a���Dž�t1��~$�;t�4��3h�&W���_����9�}�;u�W�j��_��[^_�HISTFILE.pdksh_histHOME%s/%s��Sh�
&�'&��P�����t�8u0h�
&h�
&�&��P����Ph�
&�\$S���_������$�P�e��_��[��$Id: var.c,v 1.3 1992/08/10 12:03:25 sjg Exp $S��^&S�G���C�CXV&�C,�C0S�CP���S��S���[�WVS�=�^&�w�O4�
�^&�_�&�������t�$t�BP���P����Ky�W����[^_�UWVS�|$�5�^&W�&������L$�\$��a&$tz�X^&�b&�^&�X^&&�\^&�
d^&1����a&$t"������LB�G���a&$t���~�9N|�F�4�S�?����[^_]��Ð���a&$&�6&�X^&�b&�^&�X^&&�\^&�T$�d^&�&t�X^&[^_]��Ð��X^&&��߸9����$�&����&�&�&|&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�&�t^&�S��������0b&�S��������a&�S��������v�s�������#������C�����#������5�^&��t-��UW�FP�]
���É5b&��������~4t�v4��u�UW�FP�
���ÀW�����t���[^_]���WVS�t$�=�^&V��������a&$&u'�b&�^&�X^&&�\^&�X^&[^_�RV�GP�1
���É=b&�V�-����t���[^_�0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZVS�t$�$t    V�Z     ���$u      �TV&[^Ð�$u
                   22540: �NN�A���F��}�؋^��u�
                   22541: �W^&�W^&���I1��󊒯&���u�~}I�&-��[^�%s: bad number
                   22542: S�\$�$t    S�����$t�C[Ð�X^&�\^&ShX^&������u�shL&�m���`^&[�VS�\$�t$�$uP�$&t�5b&�s�L���#��Cf�f%tVS�������5b&V�������C�&�;��X^&�\^&�5`^&hX^&S�+����uVhL&������$t S�/��[^�WVS�L$�T$�ZZ1��       �$t
                   22543: ��u�$u�!�1�[^_Ð�$t�R�Q��[^_Ð��A�
                   22544: �x����-uG�n��#u�A�A���A�X����%���a&$tM�BЃ�  w�������B���w�©�����B���w��Ʌ��o���9��g������A&ЉA�C��u���t�Y�A�����"v�A��[^_�S�\$�T$�$u5�X^&�\^&�`^&hX^&�A�����PS����������S��$t        S����[�VS�t$j=V�>��_���Å�u1�[^��V�S��������=C�
                   22545: �r)�Z�$t      R����&[^���UWVS�\$�l$�$&1���t�s�5b&0ҍ{����������щL$������������T$R������&�K�C�&�S
��t��A��&B��u��&=A��+C�C���&BA��u���t�5b&V�
��[^_]���cannot set readonly %s
                   22546: UWVS�l$�|$�����a&$&u1�[^_]Ð��>=t���a&$t�F�>u�>=u����1���f%t
                   22547: U�������U�������Á�������t�=F�$u�D$��#      ����$uv��$tp�X^&�\^&�KK�
`^&�$&t�5b&�s����#���C��uVhX^&S��������uD�#��5`^&hL&�G
�,��D$$t&�$t S��������`^&�#��5`^&S�������D$��#      ����t4f�f%&tUh�&�����$t
U�o��������VS�u������%=u �{u�$�TV&��t�SRS��������[^_]�S�\$�$&t�5b&�s����#[��T$���a&$&u1�À:t����a&$t�B�:=u�&���UWVSh�^&h&�&    ���D$$�D$ &�D$(��^&�T$���&�L$�Q�T$�i����L$�9�D$�����%=���wV����D$�T$�b&�Z4��t$���t$V�CP������t� �����[4��uފ$tW�6������'�PW�������L$(9L$ r9�\$ +\$$��h�^&��P�t$,�      ���D$$����&‰T$ &Ӊ\$(�D$ ��8�D$ M�"����L$�I4�L$��������T$(9T$ r9�\$ +\$$��h�^&��P�t$,�(      ���D$$����&��L$ &ˉ\$(�D$ ��D$ h�^&�D$$+D$($�P�t$,����[^_]���PATHIFSSECONDSOPTINDMAILMAILPATHRANDOMFCEDITCOLUMNSWV�D$��&8u��&�ǹ���u    �&^_Ð��&8u��&�ǹ���u�^_Ð����&8u��&�ǹ���u�^_Ð����&8u��&�ǹ���u�^_Ð����&8u��&�ǹ���u�^_Ð����&8u��&�ǹ     ���u�^_Ð����&8u��&�ǹ���u�^_Ð����&8u��&�ǹ���u�
                   22548: ^_Ð����&8u��&�ǹ���u�^_Ð��1�^_�S�\$�CP�~�������t
                   22549: ��t)[Ð���#�j���_��+h^&PS��������[Ð��#��$��_%���S�\$�CP�*������P��
                   22550: 9��&�$��&�&& &4&L&`&t&�&�&�&�&S���������b&j&运����[Ð�h�S�������P�|�����[Ð��j�Q��_���h^&[Ð��S�"�������&u~�����[Ð��S������P�#��[�S�n�����P�}#��[Ã#�S�������P�Z��_���[Ð�S�>�����P�� ����[�S��������Q&��
                   22551: ��Q&P[�$Id: table.c,v 1.2 1992/04/25 08:33:28 sjg Exp $�T$1ɀ:t
���HB�:u���� &���)ȍ�����D$�T$��@�@�@Ã�UWVS�|$ �\$$�w�t$�O�L$�7��P�����1�9�}�ꐐ����@9�|�_���
                   22552: ����G�o�|$���|$~u�L$�L$�t$���tM�$t<�CP�������WJ!ЍT��:t�9�u�O��&ƒ���:u��O���7S����D$�t$�L$��9D$|��7�t$����[^_]���UWVS�|$�l$�u1�[^_]Ð����[^_]Ð�GH#D$����w�5���S8UuU�CP���_����u�$u�9wu�W��&ƃ�����u�1�[^_]�UWVS�l$�t$�}ujU�n������EH#D$����}�-��S8uV�CP���_����t09}u�U��&ǃ�����u΃}�U�UP럐����[^_]Ð���8t�@�8u��u)���
P�&������C�C�>t
����F@�>u���M���[^_]��D$���D$�P�l^&�@�p^&�����p^&��p^&��t
                   22553: �$t��Ð�
l^&y�1���D$��P�D$��P���_���WVS�|$h�^&�G@��P�����ƋO��1�9_~���&�����t       �$t��C9_��)�����h�&SV����������[^_�$Id: alloc.c,v 1.2 1992/04/25 08:33:28 sjg Exp $�D$�dV&�VS�t$���t=dV&t��P����_����9u��dV&[^�allocate bad sizecannot allocateallocated object too small��UWVS�D$��uh� &�t$$������1�[^_]��Ð�H���P&�t$ ��,����&���D$�C9Ct9P����D$�9Cu�L$ �193un���&��u�&P�T$����_���ËT$�����L$ �9dV&u���t$ �����&߉{�C�C�у�c�K�s�s�D$������]�����L$ ��ŋ}�)�yh� &�t$$�T$�/������T$O���E����U��D��x��u�0�|$u�C��h� &��������L$�&��[^_]���UWVS�t$�T$�|$���uh� &W�������1�[^_]Ð�B���@��t9F�s0��WR�c������Ɖ��t�C��
�����
                   22554: ����H���u�WU��V�)�J��~�F��\��S�WS�9����[^_]�freeing with invalid areafreeing free object��UWVS�l$�\$�u�
�U9���6�F9�w�9^v�1��N9�s
                   22555: ���ϋ9�r�9�uh#&U�������[^_]��Ð��S���&؍Q�9�u�C�@A��C��   ���u�^[^_]��ËW���&��S�9�u�G�@C��G���[^_]��Ð��h�"&느$Id: io.c,v 1.3 1992/08/10 12:02:49 sjg Exp $�D$P�t$�5hb&�(��_��������D$P�t$�5hb&���_��1��r+S�\$�<�`b&u+hV$&S���_����`b&��thjjP�u��_��[�S�\$�<�`b&t"j&j�4�`b&�    ��_���4�`b&�Z��_��[�too many files open in shell
                   22556: VS�t$��   UV������j
                   22557: jV����_���Å�}�=<  `       u�����[^�h�$&�������j&jS���_��V���_���������[^�VS�\$�t$��t+S�0�����S����_����|SjV�o��_��V����_��[^�can't create pipe - try again
                   22558: S�\$S�5��_����}
h�%&�P������3��������s�      ������C[�S�\$�3�X��_���s�M��_��[�/tmp/sh%05u%02u��&WVS��$&�5xV&�xV&����_Ph&&�t$V�g��_��h�&V���_��P����_��Wj���������WV�'������C��[^_��&�$Id: eval.c,v 1.4 1992/08/12 14:15:28 sjg Exp $eval:substitute error
                   22559: VS�\$�5�`&j��
�������`&j������=&t
h�&&�������5�`&�t$�5P_&�&��[^���WVS�t$�|$ �>u   ��[^_���h�^&h��������‰T$�T$�с���L$9L$r6�\$+\$��h�^&��PR��������D$����&��L$&ˉ\$�D$��D$�L$9L$r9�\$+\$��h�^&��P�t$�������D$����&��L$&ˉ\$�D$��D$�>t�\$��WS�6����&���>u�L$9L$r9�\$+\$��h�^&��P�t$�������D$����&��L$&ˉ\$�D$��D$h�^&�D$+D$$�P�t$���������[^_�����VS�t$�\$h�^&j�O������D$�D$���D$S�D$PV�&���D$+D$��t �D$�0����(&h�^&�t$��������[^�����VS�\$�t$h�^&j��������D$�D$���D$V�D$PS����D$+D$��t ��&t�����(&���D$����$�PS�%�������h�^&�t$��������[^���eval:expand(NULL)
                   22560: %s: unset variable
                   22561: ridiculous ${} nesting
                   22562: missing value for %s
                   22563: %s
                   22564: ���UWVS�D$,��$��T$(��$��L$�D$��$�u
h�)&��������=d&t��$��f��$�f%&uY��$�$tNj{��$����_���ƅ�t7�~�&u1�~&&u�~}t%��$���$���$��������i��$�����DŽ$��h�^&h��0�������$����$���$����D$0��$��D$$��$���L$ �d$ &�t$ &��9�$�wR��$���$�&�$�h�^&��$���PS��������$����$���$���)؉��$��9D$0�Z�T$0�$��+&����+&�.&�.&�.&@/&�}E�9��&�$��+&����+&,&,&8,&,&(,&x,&�-&1��)��L$,�}E����D$,&�D$ &��������D$,��������U��$�P����D$0jU���_���h&��+�$��L$�D$���������$�j��$��{��_���h&�x&t�x&�h���1�������#t��%uc�=d&t3��$�������P�&�����=TV&u��$�h�)&�.������D$�D$0�D$(��L$,�T$(�
                   22565: �D$,���W��$���$�P����D$0�|$0uA�D$49D$u
h�)&��������D$��T$f�:��f+�$�f�J��$��J�����jU�n���������������$�$t��$���T$f�f��f��%t%f��#t��f��=tzf��?���������L$�A���$��T$(�
                   22566: �L$,�D$(�T$�PV�L$ �q�������P������P������$��D$0&�L$���������T$�B�$�P�L$�q������P�S����0��T$�B�$�9�u��$�h�)&� ���Ph�)&�������D$�D$0������$��8��$����/&�ؐ�D$0�D$,&��$��8��$����&��$����$���$���t��|$,tf��$�t�D$0�D$,�=�V&����|$u]���$��H9HrP���_�����t��$��P�:�@���������
                   22567: u�D$���|$t���t��$�W�g��_���
                   22568: �L$���uB�T$�$���$��D$��$����_��f��$����������������t0�|$,�      ��$�$�J&����%���a&�4&�|$ �&�Fh�^&��+�$�P��$���������$��D$$$ t��$�������$��D$$$t��$���$��      ���e����$��J9
                   22569: r@�+Z��h�^&��P��$��r��������$��A����Q��Y��$��&��$���&�D$ �D$$���&DŽ$��h�^&h����������$����$���$��ƅ�����������|$,����?t$��!tA��*t������[t��~tJ����$�u�|$tp��$���    D$$�S�����$�u�|$tL�~�[uF�~��u@�1���$�$ t      9�$�t��$�$u�~�=t�~�:u�L$$ ��F����d$,��D$ &���ЈF�������[^_]������WVS�\$�t$�>#���V&��ty��*t��@u��^&�P�;�F�t$�t$�j������D$�t$�N������D$0ҋ|$����������щ�Jh�^&j
                   22570: R�������P���������&[^_��Ð�����*t��@u7�=�^&�tC����|$�{���C��@��f��&f�C��$�V�������P���������u�TV&�&�T$����%t6��#t1�|$}      ��8u��;TV&u��=t��-t��?t
                   22571: �
                   22572: �����+u1���t$�=d&t�;TV&u��+tVh�)&��������[^_���funny $() command
                   22573: rcannot open $() input
                   22574: ��UWVS�l$�\$ j�������P�������ƅ�t~�>&uy�F�8uq�F�8ui�~tc�F��C����&t
h�3&�������h�3&j �s�g�����P�"��_���Dž�tW����_��P������PW���_��f�E�l��D$P�*�����h�3&�t$�i��_����j&�I�������j&�t$���_���t$���_��j8V�i����j&S�c��_��S�r��_��f�E&��u
h�3&�'�����hjjW�&��_���}�[^_]�����UWVS�|$�l$�\$ jW����_������%��
                   22575: ��#t�&=�tE=��������9�������T$�UW�(�������ue�T$�C9�v�����9�������T$�UW���������u1�T$�K9�s�����9�r}��US���������uK9�s��f����T$���[^_]��Ê�T$�h�b&W�������T$�[^_]��Ð����T$�h�^&�։�9�w��US�e�������u�C9�v��[^_]���Missing }.
                   22576: Missing comma.
                   22577: ��UWVS�|$(�|$ h�^&W�&����V�o������É\$jj{�D$$P�l$,U��&����u0�D$0%&P�t$0W�$�����h�^&S�B�����[^_]��Ð��h�^&V�������D$�|$�D$ j&j}�D$ PU�j&����u)h�^&S�������h�^&W�������ha6&��������D$�&�D$�D$�,�D$�D$��l$ ���|$ �?���t$��T$�T$j�j,V�D$,P������u)h�^&S�{�����h�^&W�m�����hm6&�P������D$ �l$jjV�D$P����t$0�t$0S�������D$ �8u�h�^&S������h�^&W�����VS�T$1��:tW����ȸ9�r��$�D8&`8&`8&l8&h8&h8&l8&h8&������FB뼉�jS���_���P&��)�&��F��[^���UWVS�L$$�L$�D$(1�1�1��t   E�������L$��L$ ��:��������D$�9D$w�L$�$��8&9&`9&�9&t9&|9&�9&��&u�z&]uU1��Q���uL�z&[u
                   22578: �&�?�����t�z&{u&G�z&}u&O�L$8J&u!��u��L$ ��L$��&[^_]��Ð�
                   22579: �BC�
                   22580: �BC�M�������&��1����BC��u��/������L$��L$ �1�[^_]�����&WVS��$&��$&�+C����jSW�D$PP����+C��9�uQ�K9r.h�^&��P�s�e������C����K�&ȉCW������[^_��&Ð�h@)�P��CP������[^_��&�.��UWVS�t$ �����|$(tj�t$����_������&�|$$�O9r:�+_��h�^&��P�|$,�w�������L$$�A����y�9�Yh�^&�t$�������L$$���&[^_]��Ð���|$9|$v�L$�&/�
                   22581: ���|$�F�D$�>/t�j/V����_���Ņ�t�EE�L$�&j�V���_����u.�T$���CB��u�J�t$(�t$(UR�t$(�����������a:&�|$�?t�D$P���_���D$�|$t~���t$�/��_����t`�X
                   22582: �x
                   22583: .u�xt�x.u�xtՀ>.u�VS���������t‹T$����CB��u�J����%�P�t$(UR�t$(�S�����뒐��t$�7��_����t�E�/[^_]���S�D$�‰��8t���:�t��AB�:u��&[�HOMEPWDOLDPWD��&UWVS��$0&��t$(��C��� &���u�;~t�F��1Ҁ{&t�{&/t�{&:u hY<&�"�����P�
�������C����{&+u�{/t�{:t�{uh^<&���{&-u2�{/t�{:t�{u hb<&�������P�������ƒ��d����C&��a&$&tS�ߍT$C���a&$t'�L$$�L$9�s����
                   22584: CB���a&$t9T$w���D$P�^���…�u
                   22585: ����������:��������
                   22586: �BF�:u�������h�^&U�n�����h�^&�D$,P�������[^_]��&�S�\$S�
�����PSh�`&�J������…�t
�$t�B[Ð�S�b��_����t�@[Ð�1�[�$Id: mail.c,v 1.2 1992/04/25 08:33:28 sjg Exp $MAILCHECKMAILPATHMAIL��PShX>&�b������Š$��R�D$HP������������=�V&uj����_����V&j���_����+�V&9D$L����V&hb>&��������…�t�$t
                   22587: ��V&�o��hk>&���������1ۅ�tX�$tR��V&�K���D$P�s���_����u,f�D$f%�f=�u�L$9Ks      S�&���L$�K�       ���C���u�[��P���@S�\$H�=�V&th�b&�5�V&��������V&��V&�D$PS�!��_����uf�D$f%�f=�u�T$��V&[��@���V&[��@�VS�\$�5�V&�k����V&h�b&S�������Å�tG����j:V����_���Å�t�Cj?V����_����t�@PV�S����V&���V&��u�[^�VS�\$��t,���ދ��uh�b&�v������h�b&V��������u�[^���@WVS�\$P�t$Th�b&j�V���������_�w�D$P�w����_����uf�D$f%�f=�u
                   22588: �T$ �W���G��[^_��@�%s
                   22589: S�D��3hA&�������5hb&����_��h�b&�3��������S��V&h�b&S���������V&��u�[�_you have mail in $_WVS�t$h�b&j���������vjhhcA&�(�������W�       ������~th�b&j�v�h�b&jheA&�������P��������W��������V&�S��V&[^_�$Id: sigact.c,v 1.5 1992/05/03 08:29:10 sjg Exp $U��VS��^&���u1҃<��^&t��^&�����B�8u��Ӆ�t�4��^&����Ѓ��Ku��e�[^��U��S��^&�=�^&t������Ѓ;u�h8B&���_�]���U��=�V&u��V&&�������V&�V&�V&S��\$�L$�T$̀��}�أ�V&�����[�VS�t$�\$�T$��t'���Ѐ:t�@�8u�)�PRV���������S���u�[^�'
                   22590:        : can't load library 'Incompatible version.
                   22591: Too many libraries.
                   22592: No such library.
                   22593: Permission denied.
                   22594: Exec format error.
                   22595: Unspecified error.
                   22596: )
                   22597:  (   ��UWVS�l$ �|$��&��V&�=�V&���P�>�V�̀����}
�ى
�V&�����������5�V&jhHC&�0hLC&�uj�������9����$�tD&���D&E&�D&E&E&E&E&E&E&E&E&E&E&�D&E&E&E&E&E&E&E&E&�D&jhcC&�:���jhzC&�.���jh�C&�"���jh�C&����jh�C&�
                   22598: ���jh�C&j��������&��̀�򐐋��T$�H��t
9L$�����6��D$�T$�����%�9�u�T$��9�}�D$&�T$��t;�jhHC&�0hLC&�uj�m�����jhcC&j�\����&��̀�򐐃��>�D���[^_]��þ�V&�=�V&t.��jh�C&��ph�C&�0h�C&j&� ��������>u֐��&1�̀���[^_]��üV&�V&�V&/lib/libc.so.4Jump table 4.2�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&�V&@KSH_VERSION=@(#)PD KSH v4.7 92/08/12tIFS=    
                   22599: &&&&&$&)&&.&1&5&&<&?&I&R&X&k&&�&�&�&�&�&�&�&�&�&
d�
&!+      7?H
PW^fqw���X&����P_&�8P�<�<�<�=�g @@@@@@@&&&&&�&�&&&
                   22600: &&&&&&
                   22601: &&&&
                   22602: &&&&&&&
                   22603: &&hX&&  ̐<�T��D�I�&R�V�]�a�k�p�u�y�����������������    ����
                   22604: �������
��
(�-�9�>�J�O�Z�a�m�r�����������������������������    �"�)�<�A�P�V���D����$�H�&����&G&�&h &dV&pV&pV&�#&�&& (>&B&�V&0F&?F&`�O&�V&

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.