Annotation of coherent/f/tmp/ksh/ksh4.7.tar, revision 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.