zsh - ksh/tcsh-like shell (part 2 of 8)
Paul John Falstad
pfalstad at phoenix.Princeton.EDU
Sat Dec 15 10:29:51 AEST 1990
---cut here---cut here---cut here---
-bash(1),
-ksh(1),
-cat(1),
-cd(1),
-chmod(1),
-cut(1),
-echo(1),
-emacs(1),
-env(1),
-gmacs(1),
-newgrp(1),
-stty(1),
-test(1),
-umask(1),
-vi(1),
-dup(2),
-exec(2),
-fork(2),
-ioctl(2),
-lseek(2),
-paste(1),
-pipe(2),
-signal(2),
-umask(2),
-ulimit(2),
-wait(2),
-rand(3),
-a.out(5),
-profile(5),
-environ(7),
-xtetris(6).
-.SH AUTHOR
-Paul Falstad <pfalstad at phoenix.princeton.edu>
-.PP
-The command line editor is a hacked-up version
-of the GNU readline library,
-written by Brian Fox (<bfox at ai.MIT.Edu>) of the Free
-Software Foundation. This shell is therefore
-under the GNU public license. I eventually plan
-to write my own command line editor to make everything
-my own code, but \fBzsh\fP will probably still be under
-the GPL, or perhaps something less restrictive.
-.SH CAVEATS
-.PP
-Using
-.B fc
-built-in command within a compound command will cause the whole
-command to disappear from the history file.
-.PP
-Shell functions are put in the function table when their declarations
-are parsed, not when they are executed. Thus function declarations
-inside \fBif\fP clauses, for example, will not work as expected.
-(This is a bug, not a caveat.)
-.PP
-The command line editor gets confused if you have termcap sequences
-(like %S) in your prompt.
-.PP
-The main shell does not get along with the command line editor.
-One of them will have to go.
-.PP
-Use of this shell is reserved for faculty, staff,
-graduate students,
-and special guests
-of the Princeton University
-Computer Science department.
End of zsh.1
echo COPYING 1>&2
sed 's/^-//' >COPYING <<'End of COPYING'
-
- GNU GENERAL PUBLIC LICENSE
- Version 1, February 1989
-
- Copyright (C) 1989 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The license agreements of most software companies try to keep users
-at the mercy of those companies. By contrast, our General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. The
-General Public License applies to the Free Software Foundation's
-software and to any other program whose authors commit to using it.
-You can use it for your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Specifically, the General Public License is designed to make
-sure that you have the freedom to give away or sell copies of free
-software, that you receive source code or can get it if you want it,
-that you can change the software or use pieces of it in new free
-programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of a such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must tell them their rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any program or other work which
-contains a notice placed by the copyright holder saying it may be
-distributed under the terms of this General Public License. The
-"Program", below, refers to any such program or work, and a "work based
-on the Program" means either the Program or any work containing the
-Program or a portion of it, either verbatim or with modifications. Each
-licensee is addressed as "you".
-
- 1. You may copy and distribute verbatim copies of the Program's source
-code as you receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice and
-disclaimer of warranty; keep intact all the notices that refer to this
-General Public License and to the absence of any warranty; and give any
-other recipients of the Program a copy of this General Public License
-along with the Program. You may charge a fee for the physical act of
-transferring a copy.
-
- 2. You may modify your copy or copies of the Program or any portion of
-it, and copy and distribute such modifications under the terms of Paragraph
-1 above, provided that you also do the following:
-
- a) cause the modified files to carry prominent notices stating that
- you changed the files and the date of any change; and
-
- b) cause the whole of any work that you distribute or publish, that
- in whole or in part contains the Program or any part thereof, either
- with or without modifications, to be licensed at no charge to all
- third parties under the terms of this General Public License (except
- that you may choose to grant warranty protection to some or all
- third parties, at your option).
-
- c) If the modified program normally reads commands interactively when
- run, you must cause it, when started running for such interactive use
- in the simplest and most usual way, to print or display an
- announcement including an appropriate copyright notice and a notice
- that there is no warranty (or else, saying that you provide a
- warranty) and that users may redistribute the program under these
- conditions, and telling the user how to view a copy of this General
- Public License.
-
- d) You may charge a fee for the physical act of transferring a
- copy, and you may at your option offer warranty protection in
- exchange for a fee.
-
-Mere aggregation of another independent work with the Program (or its
-derivative) on a volume of a storage or distribution medium does not bring
-the other work under the scope of these terms.
-
- 3. You may copy and distribute the Program (or a portion or derivative of
-it, under Paragraph 2) in object code or executable form under the terms of
-Paragraphs 1 and 2 above provided that you also do one of the following:
-
- a) accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of
- Paragraphs 1 and 2 above; or,
-
- b) accompany it with a written offer, valid for at least three
- years, to give any third party free (except for a nominal charge
- for the cost of distribution) a complete machine-readable copy of the
- corresponding source code, to be distributed under the terms of
- Paragraphs 1 and 2 above; or,
-
- c) accompany it with the information you received as to where the
- corresponding source code may be obtained. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form alone.)
-
-Source code for a work means the preferred form of the work for making
-modifications to it. For an executable file, complete source code means
-all the source code for all modules it contains; but, as a special
-exception, it need not include source code for modules which are standard
-libraries that accompany the operating system on which the executable
-file runs, or for standard header files or definitions files that
-accompany that operating system.
-
- 4. You may not copy, modify, sublicense, distribute or transfer the
-Program except as expressly provided under this General Public License.
-Any attempt otherwise to copy, modify, sublicense, distribute or transfer
-the Program is void, and will automatically terminate your rights to use
-the Program under this License. However, parties who have received
-copies, or rights to use copies, from you under this General Public
-License will not have their licenses terminated so long as such parties
-remain in full compliance.
-
- 5. By copying, distributing or modifying the Program (or any work based
-on the Program) you indicate your acceptance of this license to do so,
-and all its terms and conditions.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the original
-licensor to copy, distribute or modify the Program subject to these
-terms and conditions. You may not impose any further restrictions on the
-recipients' exercise of the rights granted herein.
-
- 7. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of the license which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-the license, you may choose any version ever published by the Free Software
-Foundation.
-
- 8. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to humanity, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
- To do so, attach the following notices to the program. It is safest to
-attach them to the start of each source file to most effectively convey
-the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19xx name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the
-appropriate parts of the General Public License. Of course, the
-commands you use may be called something other than `show w' and `show
-c'; they could even be mouse-clicks or menu items--whatever suits your
-program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- program `Gnomovision' (a program to direct compilers to make passes
- at assemblers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-That's all there is to it!
End of COPYING
echo README 1>&2
sed 's/^-//' >README <<'End of README'
-Read "INSTALL" for information on getting this shell running.
-
-zsh is free software. See the file COPYING for copying permission.
-
- This shell was "developed" by me, Paul Falstad, a sophomore at Princeton
-University. I borrowed _heavily_ from ksh, bash, tcsh, sh, and csh, as
-well as adding a few (IMHO) useful features. zsh was at first intended
-to be a subset of csh for the Commodore Amiga, but the project sort of
-ballooned; now I want it to be a cross between ksh and tcsh. It should
-be a powerful "command and programming language" that is well-designed
-and logical (like ksh), but it should also be built for humans (like
-tcsh), with all the neat features like spell checking, login/logout
-watching and termcap support that are probably too weird to make it into
-an AT&T product. This version of the shell has fallen far short of that
-goal; I just wanted to release _something_, because this is obviously
-going to be an extremely long project.
-
- This is version v1.0 of zsh. I incorporated the GNU "readline"
-editor, written by Brian Fox, into the shell, just to make my life
-temporarily easier. I made lots of changes to it, so if there are any
-bugs in the editor, they're probably my fault. readline will not be a
-part of the next version of zsh.
-
- If anyone has any questions, suggestions, comments, bugs, flames, or
-any other mail of any kind, send it to pfalstad at phoenix.princeton.edu.
-Thanks to Kartik Subbarao, Daniel Bernstein ("Yay. So sell it."),
-Kennedy Lemke, Chet Ramey (for the bash man page, and for putting features
-in the man page that weren't in our version of bash), Brian Fox (for
-helping me put off a lot of work, and for writing bash), Richard M. Stallman
-(for gdb and gcc; not for emacs though ;-) ) and many others.
-
End of README
echo INSTALL 1>&2
sed 's/^-//' >INSTALL <<'End of INSTALL'
-I was not able to port zsh to many platforms because I don't have
-accounts on many platforms. It shouldn't be too much trouble if you
-manage to decipher my code. I have tested zsh on SunOS 4.1, SunOS 4.0.3,
-4.3BSD UNIX.
-
-You need to edit the files config.h, config.local.h, makefile, and
-readline/Makefile. The comments should make clear what you have to do.
-Note that the files in the readline directory have been greatly
-modified, so you can't just copy over your changes from bash if you
-have it installed.
-
-Once you have done that, you might be able to do a make without any
-problem. If you have trouble, and can't get zsh to work, send me mail,
-and I'll try to help. If anyone manages to get zsh ported to some other
-platform, please mail me so I can tell other people about your changes
-and incorporate them into the next version.
-
End of INSTALL
echo makefile 1>&2
sed 's/^-//' >makefile <<'End of makefile'
-#! /bin/make -f
-#
-# makefile for zsh
-#
-# This file is part of zsh, the Z shell.
-#
-# zsh is free software; no one can prevent you from reading the source
-# code, or giving it to someone else.
-# This file is copyrighted under the GNU General Public License, which
-# can be found in the file called COPYING.
-#
-# Copyright (C) 1990 Paul Falstad
-#
-# zsh is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY. No author or distributor accepts
-# responsibility to anyone for the consequences of using it or for
-# whether it serves any particular purpose or works at all, unless he
-# says so in writing. Refer to the GNU General Public License
-# for full details.
-#
-# Everyone is granted permission to copy, modify and redistribute
-# zsh, but only under the conditions described in the GNU General Public
-# License. A copy of this license is supposed to have been given to you
-# along with zsh so you can know your rights and responsibilities.
-# It should be in a file named COPYING.
-#
-# Among other things, the copyright notice and this notice must be
-# preserved on all copies.
-#
-OBJS=hist.o glob.o table.o subst.o builtin.o loop.o vars.o\
-parse.o lex.o init.o jobs.o exec.o zhistory.o utils.o math.o test.o
-READLINE=readline/funmap.o readline/keymaps.o readline/readline.o
-BINDIR=/usr/local/bin
-MANDIR=/usr/local/man/man1
-CFLAGS=-O -fstrength-reduce -fomit-frame-pointer -finline-functions \
- -fsigned-char -fdelayed-branch
-CC=gcc
-ZSHPATH=zsh
-THINGS_TO_TAR=zsh.1 COPYING README INSTALL makefile sample.zshrc \
-sample.zlogin sample.zshrc.mine sample.zlogin.mine \
-alias.pro builtin.c builtin.pro config.h config.local.h \
-exec.c exec.pro funcs.h glob.c glob.pro hist.c hist.pro init.c \
-init.pro jobs.c jobs.pro lex.c lex.pro loop.c loop.pro math.c \
-math.pro parse.c parse.pro subst.c subst.pro table.c \
-table.pro test.c test.pro utils.c utils.pro vars.c vars.pro zhistory.c \
-readline/chardefs.h readline/emacs_keymap.c \
-readline/funmap.c readline/history.h readline/keymaps.c \
-readline/keymaps.h readline/readline.c readline/readline.h \
-readline/vi_keymap.c readline/vi_mode.c readline/Makefile \
-zsh.h proto
-
-.c.o:
- $(CC) $(CFLAGS) -c -o $*.o $<
-
-$(ZSHPATH): $(OBJS) $(READLINE)
- $(CC) -o $(ZSHPATH) $(OBJS) $(READLINE) -s -ltermcap
-
-$(OBJS): config.h
-
-zhistory.o: readline/history.h
-
-$(READLINE):
- cd readline;make
-
-clean:
- rm -f *.o zsh core readline/*.o
-
-install: zsh
- install -s -m 755 zsh $(BINDIR)
- install -m 444 zsh.1 $(MANDIR)
-
-tar: zsh.tar.Z
-
-zsh.tar: $(THINGS_TO_TAR)
- tar -cf zsh.tar $(THINGS_TO_TAR)
-
-zsh.tar.Z: zsh.tar
- compress -f zsh.tar
-
-shar: $(THINGS_TO_TAR)
- bundle $(THINGS_TO_TAR) > zsh.shar
-
End of makefile
echo sample.zshrc 1>&2
sed 's/^-//' >sample.zshrc <<'End of sample.zshrc'
-setenv() { export $1=$2 }
-
-umask 022
-
-PATH=$HOME/scr:$HOME/bin/$HOSTTYPE:/usr/local/bin:/usr/ucb:\
-/usr/bin:/bin:/usr/local/bin/X11:/usr/etc:/etc
-CDPATH=$HOME:/usr:/
-export MANPATH=/usr/man:/usr/local/man
-
-HISTSIZE=50
-setopt ignoreeof
-
-PROMPT='%n@%m [%h] %# '
-
-alias a alias
-
-a vi. 'vi ~/.cshrc'
-a s. '. ~/.cshrc'
-a more. 'more ~/.cshrc'
-
-chpwd() { pwd; ls -F }
-lsl() { ls -algF $* | more }
-
-a back cd -
-a h history
-a cls /usr/ucb/clear
-a type cat
-a copy cp
-a move mv
-a del rm
-a lo exit
-a lsa 'ls -aF'
-a dir 'ls -l'
-a ll 'ls -F'
-
End of sample.zshrc
echo sample.zlogin 1>&2
sed 's/^-//' >sample.zlogin <<'End of sample.zlogin'
-eval $(tset -Q -s '?xterm')
-stty dec crt kill ^U dsusp ^X
-msgs -q
-date
-biff y
-
-WATCH=$(echo $(<~/.friends) | tr ' ' :)
-MAIL=/usr/spool/mail/$USERNAME
-export DISPLAY=$(hostname):0.0
-
-limit coredumpsize 0
-/usr/games/fortune
-uptime
End of sample.zlogin
echo sample.zshrc.mine 1>&2
sed 's/^-//' >sample.zshrc.mine <<'End of sample.zshrc.mine'
-#
-# my rc file for zsh
-#
-PATH=~/scr:~/bin/$HOSTTYPE:/usr/princeton/bin:/usr/ucb:/usr/bin:/bin:\
-/u/maruchck/scr:/u/cs320/bin:/u/maruchck/bin:\
-/usr/princeton/bin/X11:/usr/etc:/etc
-CDPATH=~:~/src/cs320:~/src
-umask 022
-alias a alias
-a pd pushd
-a pop popd
-limit core 0
-a c cp
-a grep egrep
-a ps sps
-a j jobs
-a hide 'ARGV0=$(randline ~/pub/strings) '
-a rn hide /usr/princeton/bin/rn.4.1
-a v mv
-a t cat
-a where hostname'; echo >/dev/null'
-a l ls -AF
-a m make
-a mm hide less
-a talk hide talk
-a h history
-a a.out ./a.out
-a more less
-a strings strings -
-a lock lock -p
-a nw 'l -ltr | tail'
-a -a 'M' \| less
-a -a 'GF' \| fgrep -f ~/.friends
-a -a 'sub' subbarao
-a -a 'mjm' maruchck
-a -a 'paswd' '<(ypcat passwd)'
-a -a 'cex' '/u/pup/centrex'
-a rable ls -AFltrd '*(R)'
-a nrable ls -AFltrd '*(^R)'
-a ';' vi
-a 0 vi
-a '<<' more
-mostglob egrep sed
-noglob find
-PROMPT='Z %h %M:%~ '
-FCEDIT=vi
-LESSTERM=$(echo $TERMCAP | sed s/:ti=[^:]*:te=[^:]*:/:ti=:te=:/)
-a less TERMCAP='"$LESSTERM"' /usr/princeton/bin/less
-zsh=~/src/zsh
-a k9 kill -9
-cx() { chmod +x $* }
-acx() { chmod 755 $* }
-mere() { nroff -man -Tman $1 | less -s }
-
-[ `tty` = /dev/console ] || {
- PERIOD=40
- periodic() {
- echo checking news... # check news every 40 minutes
- rn -c
- }
-}
-
-randline() {
- integer z;
- z=$(wc -l <$1)
- sed -n $[RANDOM%z+1]p $1
- unset z
-}
-
-eval "proto () { $(grep -v '^#' ~/scr/proto) }"
-
-snoop() {
- (( $# )) || set `users`
- fgrep -i -f </u/pup/st{udents,aff} <(
- for i
- do
- ypmatch $i passwd
- done | cut -d: -f5 | cut -d, -f1 |
- awk '{ printf "%s,%s\n",$NF,substr($1,1,1) }')
-}
-
-MAIL=/usr/spool/mail/pfalstad
-MAILCHECK=30
-HISTSIZE=600
-setopt notify globdots autolist correct dextract pushdtohome cdablevars
-unsetopt bgnice
-WATCH=$(echo $(<~/.friends) | tr ' ' :)
-WATCHFMT='%n %a %l from %m at %t.'
-LOGCHECK=0
-
-[ -t ] && {
- (cd ; hostname >! .where)
-}
-
-export MANPATH=/usr/man:/usr/princeton/man:/u/cad/man
-
-setenv() { export $1=$2 }
-
End of sample.zshrc.mine
echo sample.zlogin.mine 1>&2
sed 's/^-//' >sample.zlogin.mine <<'End of sample.zlogin.mine'
-#
-# my login file for zsh
-#
-cd
-ls -l /etc/motd
-stty dec new cr0
-eval $(tset -s -Q '?xterm')
-stty -tabs
-umask 022
-export MAIL=/usr/spool/mail/$USER
-MAILCHECK=60
-# biff y
-msgs -fp
-uptime
-/usr/games/fortune
-log
-echo Thought for the day: $(randline ~/pub/commands)
-from 2>/dev/null
-cat .todo
-cat '. '
-echo last login $(date) on $(hostname) >! .' '
End of sample.zlogin.mine
echo alias.pro 1>&2
sed 's/^-//' >alias.pro <<'End of alias.pro'
-char *dynread(char stop);
-int filesub(void **namptr);
-char *gethome(char *user,int len);
-char *completehome(char *user,int len);
-char *getsparmval(char *s,int len);
-void setparml(char *s,int len,char *v);
-void parmsub(table list);
-void parminsall(table l,Node *nn,char **aptr,char **bptr);
-void comminsall(table l,Node *nn,char **aptr,char **bptr);
-void parmsuber(void **aptr,char **bptr);
-void modify(void **str,char **ptr);
-void tabmodify(table tab,char **ptr);
-int napply(int (*func)(void **),table list);
-int napplysplit(int (*func)(void **),table list);
-void split(Node node,table list);
-char *dstackent(int val);
-void doshfuncs(comm comm);
-void execshfunc(comm comm);
-struct anode *mkanode(char *txt,int cmflag);
-char *docompsubs(char *str,int *i);
-void docmdsubs(char **str);
-void dovarsubs(char **str);
End of alias.pro
echo builtin.c 1>&2
sed 's/^-//' >builtin.c <<'End of builtin.c'
-/*
-
- builtin.c - handles builtin commands
-
- This file is part of zsh, the Z shell.
-
- zsh is free software; no one can prevent you from reading the source
- code, or giving it to someone else.
- This file is copyrighted under the GNU General Public License, which
- can be found in the file called COPYING.
-
- Copyright (C) 1990 Paul Falstad
-
- zsh is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts
- responsibility to anyone for the consequences of using it or for
- whether it serves any particular purpose or works at all, unless he
- says so in writing. Refer to the GNU General Public License
- for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- zsh, but only under the conditions described in the GNU General Public
- License. A copy of this license is supposed to have been given to you
- along with zsh so you can know your rights and responsibilities.
- It should be in a file named COPYING.
-
- Among other things, the copyright notice and this notice must be
- preserved on all copies.
-
-*/
-
-#include "zsh.h"
-#include "funcs.h"
-#include <sys/signal.h>
-#include <sys/fcntl.h>
-#include <sys/errno.h>
-#include <utmp.h>
-#define MAXPATHLEN 1024
-
-int echo(comm comm)
-{
-table list;
-char *str;
-int nline = 1;
-
- list = comm->args;
- if (full(list))
- if (!strcmp("--",list->first->dat))
- free(getnode(list));
- else if (!strcmp("-n",list->first->dat))
- {
- free(getnode(list));
- nline = 0;
- }
- if (str = getnode(list))
- {
- printf("%s",str);
- free(str);
- while (str = getnode(list))
- {
- printf(" %s",str);
- free(str);
- }
- }
- if (nline)
- printf("\n");
- return 0;
-}
-
-/* print the directory stack */
-
-void pdstack(void)
-{
-Node node;
-
- printdir(cwd);
- for (node = dirstack->first; node; node = node->next)
- {
- putchar(' ');
- printdir(node->dat);
- }
- putchar('\n');
-}
-
-/* exit */
-
-int zexit(comm comm)
-{
- if (interact)
- if (!stopmsg)
- {
- checkjobs();
- if (stopmsg)
- {
- stopmsg = 2;
- return 1;
- }
- }
- else
- killrunjobs();
- if (islogin && unset(NORCS))
- sourcehome(".zlogout");
- if (comm && full(comm->args))
- lastval = atoi(getnode(comm->args));
- if (sigtrapped[SIGEXIT])
- dotrap(SIGEXIT);
- exit(lastval); return 0;
-}
-
-/* return */
-
-int zreturn(comm comm)
-{
- if (full(comm->args))
- lastval = atoi(getnode(comm->args));
- retflag = 1;
- return lastval;
-}
-
-int logout(comm comm)
-{
- if (!islogin)
- {
- zerrnam("logout","not login shell");
- return 1;
- }
- return zexit(comm);
-}
-
-int Unset(comm comm)
-{
-table list = comm->args;
-char *s;
-
- while (full(list))
- {
- s = getnode(list);
- unsetparm(s);
- free(s);
- }
- return 0;
-}
-
-int set(comm comm)
-{
-char *s,*t;
-
- if (!full(comm->args))
- {
- char **p = environ;
-
- while (*p)
- puts(*p++);
- listhtable(parmhtab,(void (*)(char *,char *)) pparm);
- return 0;
- }
- s = getnode(comm->args);
- t = getnode(pparms);
- freetable(pparms,freestr);
- pparms = newtable();
- addnode(pparms,t);
- while (s)
- {
- addnode(pparms,s);
- s = getnode(comm->args);
- }
- return 0;
-}
-
-struct option {
- char *name;
- char id;
- };
-
-static struct option optns[] = {
- "clobber",'1',
- "nobadpattern",'2',
- "nonomatch",'3',
- "globdots",'4',
- "notify",'5',
- "allexport",'a',
- "errexit",'e',
- "bgnice",'6',
- "ignoreeof",'7',
- "keyword",'k',
- "markdirs",'8',
- "monitor",'m',
- "noexec",'n',
- "noglob",'F',
- "norcs",'f',
- "shinstdin",'s',
- "nounset",'u',
- "verbose",'v',
- "xtrace",'x',
- "interactive",'i',
- "autolist",'9',
- "correct",'0',
- "dextract",'A',
- "nobeep",'B',
- "printexitvalue",'C',
- "pushdtohome",'D',
- "pushdsilent",'E',
- "nullglob",'G',
- "rmstarsilent",'H',
- "ignorebraces",'I',
- "cdablevars",'J',
- "nobanghist",'K',
- NULL,0
-};
-
-int setopt(comm comm)
-{
- return csetopt(comm,0);
-}
-
-int unsetopt(comm comm)
-{
- return csetopt(comm,1);
-}
-
-/* common code for setopt and unsetopt */
-
-int csetopt(comm comm,int isun)
-{
-char *s,*os,*cmd;
-int flag;
-struct option *opp;
-
- cmd = (isun) ? "unsetopt" : "setopt";
- if (!full(comm->args))
- {
- if (isun)
- return 0;
- for (opp = optns; opp->name; opp++)
- if (opts[opp->id] == OPT_SET)
- puts(opp->name);
- return 0;
- }
- while ((os = s = getnode(comm->args)) && ((flag = *s == '-') || *s == '+'))
- {
- while (*++s)
- if (*s == INTERACTIVE || *s == MONITOR)
- zerrnam(cmd,"can't change that option");
- else if (opts[*s & 0x7f] != OPT_INVALID)
- opts[*s & 0x7f] = (flag^isun) ? OPT_SET : OPT_UNSET;
- else
- zerrnam(cmd,"illegal option: %c",*s);
- free(os);
- }
- if (!s)
- return 0;
- while (s)
- {
- for (opp = optns; opp->name; opp++)
- if (!strcmp(opp->name,s))
- break;
- if (opp->name)
- {
- if (opp->id == INTERACTIVE || opp->id == MONITOR)
- zerrnam(cmd,"can't change that option");
- else
- opts[opp->id] = (isun) ? OPT_UNSET : OPT_SET;
- }
- else
- {
- zerrnam(cmd,"no such option: %s",s);
- free(s);
- return 1;
- }
- free(s);
- s = getnode(comm->args);
- }
- return 0;
-}
-
-/* print a positional parameter */
-
-void pparm(char *s,struct pmnode *t)
-{
- if (s && t)
- if (t->isint)
- printf("%s=%ld\n",s,t->u.val);
- else
- {
- printf("%s=",s);
- niceprint(t->u.str);
- putchar('\n');
- }
-}
-
-int dirs(comm comm)
-{
- if (comm->args->first)
- {
- if (dirstack)
- freetable(dirstack,freestr);
- dirstack = comm->args;
- comm->args = NULL;
- }
- else
- pdstack();
- return 0;
-}
-
-/* call func once for each entry in a hash table */
-
-void listhtable(htable ht,void (*func)(char *,char *))
-{
-int t0;
-struct hnode *hn;
-
- for (t0 = ht->hsize-1; t0 >= 0; t0--)
- for (hn = ht->nodes[t0]; hn; hn = hn->hchain)
- func(hn->nam,hn->dat);
-}
-
-/* print an alias (used with listhtable) */
-
-void palias(char *s,struct anode *t)
-{
- if (t && t->cmd >= 0)
- {
- printf((t->cmd) ? "alias %-13s " : "alias -a %-10s ",s);
- niceprint(t->text);
- putchar('\n');
- }
-}
-
-/* print a shell function (used with listhtable) */
-
-void pshfunc(char *s,list l)
-{
-char *t;
-
- t = getltext(l);
- untokenize(t);
- printf("%s() {\n%s\n}\n",s,t);
- free(t);
-}
-
-void niceprint(char *s)
-{
- niceprintf(s,stdout);
-}
-
-void niceprintf(char *s,FILE *f)
-{
- for (; *s; s++)
- {
- if (*s >= 32 && *s <= 126)
- fputc(*s,f);
- else if (*s == '\n')
- {
- putc('\\',f);
- putc('n',f);
- }
- else
- {
- putc('^',f);
- fputc(*s | 0x40,f);
- }
- }
-}
-
-/* build a command line from a linked list */
-
-char *buildline(table t)
-{
-char *str = strdup(""),*s,*os;
-
- while (s = getnode(t))
- {
- os = str;
- str = (*os) ? tricat(os," ",s) : strdup(s);
- free(s);
- free(os);
- }
- return str;
-}
-
-int Alias(comm comm)
-{
-char *s1,*s2;
-int anyflag = 0;
-
- if (!(s1 = getnode(comm->args)))
- {
- listhtable(alhtab,(void (*)(char *,char *)) palias);
- return 0;
- }
- if (!strcmp(s1,"-a"))
- {
- anyflag = 1;
- free(s1);
- if (!(s1 = getnode(comm->args)))
- {
- zerrnam("alias","alias -a requires 2 arguments");
- return 1;
- }
- }
- if (!comm->args->first)
- {
- palias(s1,gethnode(s1,alhtab));
- free(s1);
- return 0;
- }
- s2 = buildline(comm->args);
- addhnode(s1,mkanode(s2,!anyflag),alhtab,freeanode);
- return 0;
-}
-
-int cd(comm comm)
-{
- if (!full(comm->args))
- return chcd("cd",strdup(getparm("HOME")));
- if (comm->args->first->next)
- {
- char *s,*t,*u,*v;
- int sl,tl;
-
- if (comm->args->first->next->next)
- {
- zerrnam("cd","too many arguments");
- return 1;
- }
- s = getnode(comm->args);
- t = getnode(comm->args);
- if (!(u = (char *) strstr(cwd,s)))
- {
- zerrnam("cd","string not in pwd: %s",s);
- return 1;
- }
- sl = strlen(s);
- tl = strlen(t);
- v = zalloc((u-cwd)+tl+strlen(u+sl)+1);
- strncpy(v,cwd,u-cwd);
- strcpy(v+(u-cwd),t);
- strcat(v,u+sl);
- free(s);
- free(t);
- return chcd("cd",v);
- }
- return chcd("cd",getnode(comm->args));
-}
-
-int dot(comm comm)
-{
-char *s;
-
- if (!full(comm->args))
- return 1;
- s = getnode(comm->args);
- if (source(s))
- {
- zerrnam(".","%e: %s",errno,s);
- free(s);
- return 1;
- }
- free(s);
- return 0;
-}
-
-int Umask(comm comm)
-{
-char *s,*t;
-int t0;
-
- if (!full(comm->args))
- {
- t0 = umask(0);
- umask(t0);
- printf("%03o\n",t0);
- return 0;
- }
- s = getnode(comm->args);
- t0 = strtol(s,&t,8);
- if (*t)
- {
- zerrnam("umask","bad umask");
- free(s);
- return 1;
- }
- umask(t0);
- free(s);
- return 0;
-}
-
-int which(comm comm)
-{
-struct chnode *chn;
-struct anode *a;
-char *str = getnode(comm->args),*cnam;
-
- if (!str)
- {
- zerrnam("which","argument required");
- return 1;
- }
- if ((a = gethnode(str,alhtab)) && a->cmd)
- {
- if (a->cmd < 0)
- printf("%s: shell reserved word\n",str);
- else
- printf("%s: aliased to %s\n",str,a->text);
- free(str);
- return 0;
- }
- if (gethnode(str,shfunchtab))
- printf("%s: shell function\n",str);
- else if (chn = gethnode(str,chtab))
- {
- if (chn->type != BUILTIN)
- puts(chn->u.nam);
- else
- printf("%s: shell built-in command\n",str);
- }
- else if (!(cnam = findcmd(str)))
- {
- zerr("command not found: %s",str);
- free(str);
- return 1;
- }
- else
- puts(cnam);
- free(str);
- return 0;
-}
-
-int popd(comm comm)
-{
-int val = 0;
-char *s;
-Node node;
-
- if (comm->args->first && *(s = comm->args->first->dat) == '+')
- val = atoi(s+1);
- if (val--)
- {
- if (val < 0)
- node = dirstack->last;
- else
- for (node = dirstack->first; val && node; node = node->next,
- val--);
- free(remnode(dirstack,node));
- if (unset(PUSHDSILENT))
- pdstack();
- return 0;
- }
- else
- {
- if (!full(dirstack))
- {
- zerrnam("popd","dir stack empty");
- return 1;
- }
- val = chcd("popd",getnode(dirstack));
- if (unset(PUSHDSILENT))
- pdstack();
- return val;
- }
-}
-
-int pushd(comm comm)
-{
-char *s;
-int num;
-
- if (comm->args->first)
- {
- s = getnode(comm->args);
-
- if (*s == '+')
- {
- if (!(num = atoi(s+1)))
- {
- free(s);
- return 0;
- }
- free(s);
- if (isset(DEXTRACT))
- {
- Node n = dirstack->first;
-
- insnode(dirstack,(Node) dirstack,strdup(cwd));
- while (--num && n)
- n = n->next;
- if (!n)
- {
- zerrnam("pushd","not that many dir stack entries");
- return 1;
- }
- insnode(dirstack,(Node) dirstack,remnode(dirstack,n));
- }
- else
- {
- addnode(dirstack,strdup(cwd));
- while(--num)
- addnode(dirstack,getnode(dirstack));
- }
- num = chcd("pushd",getnode(dirstack));
- if (unset(PUSHDSILENT))
- pdstack();
- return num;
- }
- pushnode(dirstack,strdup(cwd));
- num = chcd("pushd",s);
- if (num)
- free(getnode(dirstack));
- else if (unset(PUSHDSILENT))
- pdstack();
- return num;
- }
- else
- {
- char *s;
-
- if (isset(PUSHDTOHOME))
- s = strdup(getparm("HOME"));
- else
- s = getnode(dirstack);
- if (!s)
- {
- zerrnam("pushd","dir stack empty");
- return 1;
- }
- pushnode(dirstack,strdup(cwd));
- num = chcd("pushd",s);
- if (num)
- free(getnode(dirstack));
- else if (unset(PUSHDSILENT))
- pdstack();
- return num;
- }
-}
-
-/* common code for pushd, popd, cd */
-
-int chcd(char *cnam,char *cd)
-{
-char *s,*t;
-char buf[MAXPATHLEN],*new = cd;
-int t0,val,esav,pnew = 0;
-
- if (cd[0] == '-' && !cd[1])
- {
- free(cd);
- cd = getparm("OLDPWD");
- cd = strdup((cd) ? cd : ".");
- }
- if (*cd == '/')
- {
- val = chdir(new = cd);
- esav = errno;
- }
- else
- for (t0 = 0; t0 != cdpathct; t0++)
- {
- sprintf(buf,"%s/%s",cdpath[t0],cd);
- if ((val = chdir(new = buf)) != -1)
- {
- if (t0)
- pnew = 1;
- break;
- }
- if (t0 && errno != ENOENT && errno != ENOTDIR)
- zerrnam(cnam,"warning: %e: %s",errno,buf);
- if (!t0)
- esav = errno;
- }
- if (val == -1 && errno == ENOENT)
- {
- t = strdup(cd);
- if (isset(CDABLEVARS) && (s = getparm(t)) && *s == '/')
- if (chdir(new = s) != -1)
- {
- val = 0;
- pnew = 1;
- goto goneto;
- }
- free(t);
- zerrnam(cnam,"%e: %s",esav,cd);
- free(cd);
- return 1;
- }
-goneto:
- if (val == -1)
- {
- zerrnam(cnam,"%e: %s",esav,cd);
- free(cd);
- return 1;
- }
- else
- {
- list l;
-
- if (cwd)
- setparm(strdup("OLDPWD"),cwd,0,0);
- cwd = findcwd(new);
- setparm(strdup("PWD"),strdup(cwd),0,0);
- if (pnew)
- {
- printdir(cwd);
- putchar('\n');
- }
- if (l = gethnode("chpwd",shfunchtab))
- newrunlist(l);
- }
- return 0;
-}
-
-int shift(comm comm)
-{
-char *s;
-int sh = 1;
-
- if (comm->args->first && (s = comm->args->first->dat))
- sh = atoi(s);
- while (sh-- && pparms->first->next)
- remnode(pparms,pparms->first->next);
- return 0;
-}
-
-int unhash(comm comm)
-{
-char *s;
-
- if (!(s = getnode(comm->args)))
- {
- zerrnam("unhash","argument required");
- return 1;
- }
- while (s)
- {
- if (!gethnode(s,chtab))
- {
- zerrnam("unhash","not in command table: %s",s);
- return 1;
- }
- free(remhnode(s,chtab));
- free(s);
- s = getnode(comm->args);
- }
- return 0;
-}
-
-int rehash(comm comm)
-{
- parsepath();
- return 0;
-}
-
-int hash(comm comm)
-{
-char *s,*t;
-struct chnode *chn;
-
- if (!(s = getnode(comm->args)) || !(t = getnode(comm->args)))
- {
- zerrnam("hash","not enough arguments");
- if (s)
- free(s);
- return 1;
- }
- chn = alloc(sizeof(struct chnode));
- chn->type = EXCMD_PREDOT;
- chn->globstat = GLOB;
- chn->u.nam = t;
- addhnode(s,chn,chtab,freechnode);
- return 0;
-}
-
-int Break(comm comm)
-{
-char *s;
-
- if (!loops)
- {
- zerrnam("break","not in loop");
- return 1;
- }
- if (!(s = getnode(comm->args)))
- breaks = 1;
- else if (atoi(s))
- {
- breaks = atoi(s);
- free(s);
- }
- else
- {
- zerrnam("break","numeric argument required");
- free(s);
- return 1;
- }
- return 0;
-}
-
-int colon(comm comm)
-{
- return 0;
-}
-
-int Glob(comm comm)
-{
-struct chnode *chn;
-char *s;
-
- while (s = getnode(comm->args))
- {
- chn = gethnode(s,chtab);
- free(s);
- if (chn)
- chn->globstat = GLOB;
- }
- return 0;
-}
-
-int noglob(comm comm)
-{
-struct chnode *chn;
-char *s;
-
- while (s = getnode(comm->args))
- {
- chn = gethnode(s,chtab);
- free(s);
- if (chn)
- chn->globstat = NOGLOB;
- }
- return 0;
-}
-
-int mostglob(comm comm)
-{
-struct chnode *chn;
-char *s;
-
- while (s = getnode(comm->args))
- {
- chn = gethnode(s,chtab);
- free(s);
- if (chn)
- chn->globstat = MOSTGLOB;
- }
- return 0;
-}
-
-int unfunction(comm comm)
-{
-char *s1;
-list l;
-
- while (s1 = getnode(comm->args))
- {
- unsettrap(s1);
- if (l = remhnode(s1,shfunchtab))
- freelist(l);
- free(s1);
- }
- return 0;
-}
-
-int unalias(comm comm)
-{
-char *s1;
-struct anode *an;
-
- while (s1 = getnode(comm->args))
- {
- if (an = remhnode(s1,alhtab))
- freeanode(an);
- free(s1);
- }
- return 0;
-}
-
-/* != 0 if s is a prefix of t */
-
-int prefix(char *s,char *t)
-{
- while (*s && *t && *s == *t) s++,t++;
- return (!*s);
-}
-
-/* convert %%, %1, %foo, %?bar? to a job number */
-
-int getjob(char *s,char *prog)
-{
-int t0,retval;
-char *os = s;
-
- if (*s++ != '%')
- {
- zerrnam(prog,"bad job specifier");
- retval = -1; goto done;
- }
- if (*s == '%' || *s == '+' || !*s)
- {
- if (topjob == -1)
- {
- zerrnam(prog,"no current job");
- retval = -1; goto done;
- }
- retval = topjob; goto done;
- }
- if (*s == '-')
- {
- if (prevjob == -1)
- {
- zerrnam(prog,"no previous job");
- retval = -1; goto done;
- }
- retval = prevjob; goto done;
- }
- if (isdigit(*s))
- {
- t0 = atoi(s);
- if (t0 && t0 < MAXJOB && jobtab[t0].stat && t0 != curjob)
- { retval = t0; goto done; }
- zerrnam(prog,"no such job");
- retval = -1; goto done;
- }
- if (*s == '?')
- {
- struct procnode *pn;
-
- for (t0 = 0; t0 != MAXJOB; t0++)
- if (jobtab[t0].stat && t0 != curjob)
- for (pn = jobtab[t0].procs; pn; pn = pn->next)
- if (strstr(pn->text,s+1))
- { retval = t0; goto done; }
- zerrnam(prog,"job not found: %s",s);
- retval = -1; goto done;
- }
- for (t0 = 0; t0 != MAXJOB; t0++)
- if (jobtab[t0].stat && jobtab[t0].procs && t0 != curjob &&
- prefix(s,jobtab[t0].procs->text))
- { retval = t0; goto done; }
- zerrnam(prog,"job not found: %s",s);
- retval = -1;
-done:
- free(os);
- return retval;
-}
-
-int fg(comm comm)
-{
-char *s1;
-int ocj = curjob,job;
-
- scanjobs();
- if (!jobbing)
- {
- zerr("no job control in this shell.");
- return 1;
- }
- if (s1 = getnode(comm->args))
- job = getjob(s1,"fg");
- else
- {
- if (topjob == -1 || topjob == curjob)
- {
- zerrnam("fg","no current job");
- return 1;
- }
- job = topjob;
- }
- if (job == -1)
- return 1;
- makerunning(jobtab+job);
- if (topjob == job)
- {
- topjob = prevjob;
- prevjob = job;
- }
- if (prevjob == job)
- setprevjob();
- printjob(jobtab+job,-1);
- curjob = job;
- if (strcmp(jobtab[job].cwd,cwd))
- {
- printf("(pwd: ");
- printdir(jobtab[job].cwd);
- printf(")\n");
- }
- settyinfo(&jobtab[job].ttyinfo);
- attachtty(jobtab[job].gleader);
- killpg(jobtab[job].gleader,SIGCONT);
- waitjobs();
- curjob = ocj;
- return 0;
-}
-
-int bg(comm comm)
-{
-char *s1;
-int job,stopped;
-
- scanjobs();
- if (!jobbing)
- {
- zerr("no job control in this shell.");
- return 1;
- }
- if (s1 = getnode(comm->args))
- job = getjob(s1,"bg");
- else
- {
- if (topjob == -1 || topjob == curjob)
- {
- zerrnam("bg","no current job");
- return 1;
- }
- job = topjob;
- }
- if (job == -1)
- return 1;
- if (!(jobtab[job].stat & STAT_STOPPED))
- {
- zerrnam("bg","job already in background");
- return 1;
- }
- stopped = jobtab[job].stat & STAT_STOPPED;
- if (stopped)
- makerunning(jobtab+job);
- if (topjob == job)
- {
- topjob = prevjob;
- prevjob = -1;
- }
- if (prevjob == job)
- prevjob = -1;
- if (prevjob == -1)
- setprevjob();
- if (topjob == -1)
- {
- topjob = prevjob;
- setprevjob();
- }
- printjob(jobtab+job,(stopped) ? -1 : 0);
- if (stopped)
- killpg(jobtab[job].gleader,SIGCONT);
- return 0;
-}
-
-int jobs(comm comm)
-{
-int job,lng = 0;
-
- if (full(comm->args))
- {
- if (comm->args->first->next || (strcmp(comm->args->first->dat,"-l")
- && strcmp(comm->args->first->dat,"-p")))
- {
- zerrnam("jobs","usage: jobs [ -lp ]");
- return 1;
- }
- lng = (strcmp(comm->args->first->dat,"-l")) ? 2 : 1;
- }
- for (job = 0; job != MAXJOB; job++)
- if (job != curjob && jobtab[job].stat)
- printjob(job+jobtab,lng);
- stopmsg = 2;
- return 0;
-}
-
-int Kill(comm comm)
-{
-int sig = SIGTERM;
-char *s;
-
- s = getnode(comm->args);
- if (s && *s == '-')
- {
- if (isdigit(s[1]))
- sig = atoi(s+1);
- else
- {
- if (s[1] == 'l' && s[2] == '\0')
- {
- printf("%s",sigs[0]);
- for (sig = 1; sig != SIGCOUNT; sig++)
- printf(" %s",sigs[sig]);
- putchar('\n');
- return 0;
- }
- for (sig = 0; sig != SIGCOUNT; sig++)
- if (!strcmp(sigs[sig],s+1))
- break;
- if (sig == SIGCOUNT)
- {
- zerrnam("kill","unknown signal: SIG%s",s+1);
- zerrnam("kill","type kill -l for a list of signals");
- return 1;
- }
- }
- s = getnode(comm->args);
- }
- while (s)
- {
- if (*s == '%')
- {
- int job = getjob(s,"kill");
-
- if (killjb(jobtab+job,sig) == -1)
- {
- zerrnam("kill","kill failed: %e",errno);
- return 1;
- }
- if (jobtab[job].stat & STAT_STOPPED && sig == SIGCONT)
- jobtab[job].stat &= ~STAT_STOPPED;
- if (sig != SIGKILL)
- killpg(jobtab[job].gleader,SIGCONT);
- }
- else
- if (kill(atoi(s),sig) == -1)
- {
- zerrnam("kill","kill failed: %e");
- return 1;
- }
- s = getnode(comm->args);
- }
- return 0;
-}
-
-int export(comm comm)
-{
-char *s,*t;
-struct pmnode *pm;
-
- while (s = getnode(comm->args))
- {
- if (t = strchr(s,'='))
- {
- *t = '\0';
- if (pm = gethnode(s,parmhtab))
- freepm(remhnode(s,parmhtab));
- *t = '=';
- putenv(s);
- }
- else
- {
- if (!(pm = gethnode(s,parmhtab)))
- {
- if (!getenv(s))
- {
- zerrnam("export","parameter not set: %s",s);
- free(s);
- return 1;
- }
- }
- else if (pm->isint)
- {
- zerrnam("export","can't export integer parameters");
- free(s);
- return 1;
- }
- else
- {
- t = tricat(s,"=",pm->u.str);
- putenv(t);
- free(remhnode(s,parmhtab));
- }
- }
- }
- return 0;
-}
-
-int integer(comm comm)
-{
-char *s,*t;
-struct pmnode *uu;
-
- while (s = getnode(comm->args))
- {
- if (t = strchr(s,'='))
- {
- *t = '\0';
- setparm(s,t+1,0,1);
- *t = '=';
- }
- else
- {
- uu = gethnode(s,parmhtab);
- if (uu)
- {
- if (!uu->isint)
- {
- uu->isint = 1;
- uu->u.val = matheval(uu->u.str);
- }
- }
- else
- setiparm(s,0,1);
- }
- }
- return 0;
-}
-
-static char *recs[] = {
- "cputime","filesize","datasize","stacksize","coredumpsize",
- "resident","descriptors"
- };
-
-int limit(comm comm)
-{
-char *s;
-int hard = 0,t0,lim;
-long val;
-
- if (!(s = getnode(comm->args)))
- {
- showlimits(0,-1);
- return 0;
- }
- if (!strcmp(s,"-s"))
- {
- if (full(comm->args))
- zerr("limit","arguments after -s ignored");
- for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
- if (setrlimit(t0,limits+t0) < 0)
- zerr("limit","setrlimit failed: %e",errno);
- return 0;
- }
- if (!strcmp(s,"-h"))
- {
- hard = 1;
- free(s);
- if (!(s = getnode(comm->args)))
- {
- showlimits(1,-1);
- return 0;
- }
- }
- while (s)
- {
- for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
- if (!strncmp(recs[t0],s,strlen(s)))
- {
- if (lim != -1)
- lim = -2;
- else
- lim = t0;
- }
- if (lim < 0)
- {
- zerrnam("limit",
- (lim == -2) ? "ambiguous resource specification: %s"
- : "no such resource: %s",s);
- free(s);
- return 1;
- }
- free(s);
- if (!(s = getnode(comm->args)))
- {
- showlimits(hard,lim);
- return 0;
- }
- if (!lim)
- {
- char *ss = s;
-
- val = strtol(s,&s,10);
- if (*s)
- if ((*s == 'h' || *s == 'H') && !s[1])
- val *= 3600L;
- else if ((*s == 'm' || *s == 'M') && !s[1])
- val *= 60L;
- else if (*s == ':')
- val = val*60+strtol(s+1,&s,10);
- else
- {
- zerrnam("limit","unknown scaling factor: %s",s);
- free(ss);
- return 1;
- }
- }
-#ifdef RLIMIT_NOFILE
- else if (lim == RLIMIT_NOFILE)
- val = strtol(s,&s,10);
-#endif
- else
- {
- char *ss = s;
-
- val = strtol(s,&s,10);
- if (!*s || ((*s == 'k' || *s == 'K') && !s[1]))
- val *= 1024L;
- else if ((*s == 'M' || *s == 'm') && !s[1])
- val *= 1024L*1024;
- else
- {
- zerrnam("limit","unknown scaling factor: %s",s);
- free(ss);
- return 1;
- }
- free(ss);
- }
- if (hard)
- if (val > limits[lim].rlim_max && geteuid())
- {
- zerrnam("limit","can't raise hard limits");
- return 1;
- }
- else
- {
- limits[lim].rlim_max = val;
- if (limits[lim].rlim_max < limits[lim].rlim_cur)
- limits[lim].rlim_cur = limits[lim].rlim_max;
- }
- else
- if (val > limits[lim].rlim_max)
- {
- zerrnam("limit","limit exceeds hard limit");
- return 1;
- }
- else
- limits[lim].rlim_cur = val;
- s = getnode(comm->args);
- }
- return 0;
-}
-
-int unlimit(comm comm)
-{
-char *s = getnode(comm->args);
-int hard = 0,t0,lim;
-
- if (s && !strcmp(s,"-h"))
- {
- hard = 1;
- if (geteuid())
- {
- zerrnam("unlimit","can't remove hard limits");
- return 1;
- }
- free(s);
- s = getnode(comm->args);
- }
- if (!s)
- {
- for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
- {
- if (hard)
- limits[t0].rlim_max = RLIM_INFINITY;
- else
- limits[t0].rlim_cur = limits[t0].rlim_max;
- }
- return 0;
- }
- while (s)
- {
- for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
- if (!strncmp(recs[t0],s,strlen(s)))
- {
- if (lim != -1)
- lim = -2;
- else
- lim = t0;
- }
- if (lim < 0)
- {
- zerrnam("unlimit",
- (lim == -2) ? "ambiguous resource specification: %s"
- : "no such resource: %s",s);
- free(s);
- return 1;
- }
- free(s);
- if (hard)
- limits[lim].rlim_max = RLIM_INFINITY;
- else
- limits[lim].rlim_cur = limits[lim].rlim_max;
- s = getnode(comm->args);
- }
- return 0;
-}
-
-void showlimits(int hard,int lim)
-{
-int t0;
-long val;
-
- for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
- if (t0 == lim || lim == -1)
- {
- printf("%-16s",recs[t0]);
- val = (hard) ? limits[t0].rlim_max : limits[t0].rlim_cur;
- if (val == RLIM_INFINITY)
- printf("unlimited\n");
- else if (!t0)
- printf("%d:%02d:%02d\n",(int) (val/3600),
- (int) (val/60) % 60,(int) (val % 60));
-#ifdef RLIMIT_NOFILE
- else if (t0 == RLIMIT_NOFILE)
- printf("%d\n",(int) val);
-#endif
- else if (val >= 1024L*1024L)
- printf("%ldMb\n",val/(1024L*1024L));
- else
- printf("%ldKb\n",val/1024L);
- }
-}
-
-int sched(comm comm)
-{
-char *s = getnode(comm->args);
-time_t t;
-long h,m;
-struct tm *tm;
-struct schnode *sch,*sch2,*schl;
-int t0;
-
- if (s && *s == '-')
- {
- t0 = atoi(s+1);
-
- if (!t0)
- {
- zerrnam("sched","usage for delete: sched -<item#>.");
- return 1;
- }
- for (schl = (struct schnode *) &scheds, sch = scheds, t0--;
- sch && t0; sch = (schl = sch)->next, t0--);
- if (!sch)
- {
- zerrnam("sched","not that many entries");
- return 1;
- }
- schl->next = sch->next;
- free(sch->cmd);
- free(sch);
- return 0;
- }
- if (s && !full(comm->args))
- {
- zerrnam("sched","not enough arguments");
- return 1;
- }
- if (!s)
- {
- char tbuf[40];
-
- for (t0 = 1, sch = scheds; sch; sch = sch->next,t0++)
- {
- t = sch->time;
- tm = localtime(&t);
- strftime(tbuf,20,"%a %b %e %k:%M:%S",tm);
- printf("%3d %s %s\n",t0,tbuf,sch->cmd);
- }
- return 0;
- }
- if (*s == '+')
- {
- h = strtol(s+1,&s,10);
- if (*s != ':')
- {
- zerrnam("sched","bad time specifier");
- return 1;
- }
- m = strtol(s+1,&s,10);
- if (*s)
- {
- zerrnam("sched","bad time specifier");
- return 1;
- }
- t = time(NULL)+h*3600+m*60;
- }
- else
- {
- h = strtol(s,&s,10);
- if (*s != ':')
- {
- zerrnam("sched","bad time specifier");
- return 1;
- }
- m = strtol(s+1,&s,10);
- if (*s && *s != 'a' && *s != 'p')
- {
- zerrnam("sched","bad time specifier");
- return 1;
- }
- t = time(NULL);
- tm = localtime(&t);
- t -= tm->tm_sec+tm->tm_min*60+tm->tm_hour*3600;
- if (*s == 'p')
- h += 12;
- t += h*3600+m*60;
- if (t < time(NULL))
- t += 3600*24;
- }
- sch = alloc(sizeof(struct schnode));
- sch->time = t;
- sch->cmd = buildline(comm->args);
- sch->next = NULL;
- for (sch2 = (struct schnode *) &scheds; sch2->next; sch2 = sch2->next);
- sch2->next = sch;
- return 0;
-}
-
-int eval(comm comm)
-{
-char *s = buildline(comm->args);
-list list;
-
- hungets(s);
- strinbeg();
- if (!(list = parlist(1)))
- {
- hflush();
- strinend();
- return 1;
- }
- strinend();
- runlist(list);
- return lastval;
-}
-
-int Brk(comm comm)
-{
- printf("%lx\n",(long) sbrk(0));
- return 0;
-}
-
-static struct utmp *wtab;
-static int wtabsz;
-
-int log(comm comm)
-{
- if (!getparm("WATCH"))
- return 1;
- if (wtab)
- free(wtab);
- wtab = (struct utmp *) zalloc(1);
- wtabsz = 0;
- watch();
- return 0;
-}
-
-int let(comm comm)
-{
-char *str;
-long val;
-
- while (str = getnode(comm->args))
- val = matheval(str);
- return !val;
-}
-
-int Read(comm comm)
-{
-char *str,*pmpt;
-int r = 0,bsiz,c,gotnl = 0;
-char *buf,*bptr;
-char cc;
-
- str = getnode(comm->args);
- if (str && !strcmp(str,"-r"))
- {
- r = 1;
- str = getnode(comm->args);
- }
- if (!str)
- str = strdup("REPLY");
- if (interact)
- {
- for (pmpt = str; *pmpt && *pmpt != '?'; pmpt++);
- if (*pmpt++)
- {
- write(2,pmpt,strlen(pmpt));
- *pmpt = '\0';
- }
- }
- while (full(comm->args))
- {
- buf = bptr = zalloc(bsiz = 64);
- FOREVER
- {
- if (gotnl)
- break;
- if (read(0,&cc,1) == 1)
- c = cc;
- else
- c = EOF;
- if (c == EOF || znspace(c))
- break;
- *bptr++ = c;
- if (bptr == buf+bsiz)
- {
- buf = realloc(buf,bsiz *= 2);
- bptr = buf+(bsiz/2);
- }
- }
- if (c == EOF)
- return 1;
- if (c == '\n')
- gotnl = 1;
- *bptr = '\0';
- setparm(str,buf,0,0);
- str = getnode(comm->args);
- }
- buf = bptr = zalloc(bsiz = 64);
- if (!gotnl)
- FOREVER
- {
- if (read(0,&cc,1) == 1)
- c = cc;
- else
- c = EOF;
- if (c == EOF || c == '\n')
- break;
- *bptr++ = c;
- if (bptr == buf+bsiz)
- {
- buf = realloc(buf,bsiz *= 2);
- bptr = buf+(bsiz/2);
- }
- *bptr = '\0';
- }
- if (c == EOF)
- return 1;
- setparm(str,buf,0,0);
- return 0;
-}
-
-int fc(comm comm)
-{
-char *ename = getparm("FCEDIT"),*str,*s;
-int n = 0,l = 0,r = 0,first = -1,last = -1,retval;
-table subs = NULL;
-
- if (!interact)
- {
- zerrnam("fc","not interactive shell");
- return 1;
- }
- remhist();
- if (!ename)
- ename = DEFFCEDIT;
- str = getnode(comm->args);
- for (; str && *str == '-' && str[1] && !isdigit(str[1]);
- str = getnode(comm->args))
- while (str[1])
- switch(*++str)
- {
- case 'e':
- if (str[1])
- {
- zerrnam("fc","editor name expected after -e");
- return 1;
- }
- ename = getnode(comm->args);
- if (!ename)
- {
- zerrnam("fc","editor name expected after -e");
- return 1;
- }
- break;
- case 'n':
- n = 1;
- break;
- case 'l':
- l = 1;
- break;
- case 'r':
- r = 1;
- break;
- default:
- zerrnam("fc","bad option: %c",*str);
- return 1;
- }
- subs = newtable();
- while (str)
- {
- for (s = str; *s && *s != '='; s++);
- if (!*s)
- break;
- *s++ = '\0';
- addnode(subs,str);
- addnode(subs,s);
- str = getnode(comm->args);
- }
- if (str)
- {
- first = fcgetcomm(str);
- if (first == -1)
- {
- freetable(subs,freestr);
- return 1;
- }
- str = getnode(comm->args);
- }
- if (str)
- {
- last = fcgetcomm(str);
- if (last == -1)
- {
- freetable(subs,freestr);
- return 1;
- }
- if (full(comm->args))
- {
- zerrnam("fc","too many arguments");
- freetable(subs,freestr);
- return 1;
- }
- }
- if (first == -1)
- {
- first = (l) ? cev-16 : cev;
- if (last == -1)
- last = cev;
- }
- if (first < tfev)
- first = tfev;
- if (last == -1)
- last = first;
- if (l)
- retval = fclist(stdout,!n,r,first,last,subs);
- else
- {
- FILE *out;
- char *fn = gettemp();
-
- out = fopen(fn,"w");
- if (!out)
- zerrnam("fc","can't open temp file: %e",errno);
- else
- {
- retval = 1;
- if (!fclist(out,0,r,first,last,subs))
- if (fcedit(ename,fn))
- if (stuff(fn))
- zerrnam("fc","%e: %s",errno,s);
- else
- retval = 0;
- }
- unlink(fn);
- free(fn);
- }
- freetable(subs,freestr);
- return retval;
-}
-
-/* get the history event associated with s */
-
-int fcgetcomm(char *s)
-{
-int cmd;
-
- if (cmd = atoi(s))
- {
- if (cmd < 0)
- cmd = cev+cmd+1;
- return cmd;
- }
- cmd = hcomsearch(s);
- if (cmd == -1)
- zerrnam("fc","event not found: %s",s);
- return cmd;
-}
-
-/* list a series of history events to a file */
-
-int fclist(FILE *f,int n,int r,int first,int last,table subs)
-{
-int done = 0,ct;
-Node node;
-char *s;
-
- if (!subs->first)
- done = 1;
- last -= first;
- first -= tfev;
- if (r)
- first += last;
- for (node = histlist->first,ct = first; ct && node;
- node = node->next, ct--);
- first += tfev;
- while (last-- >= 0)
- {
- if (!node)
- {
- zerrnam("fc","no such event: %d",first);
- return 1;
- }
- s = makehlist(node->dat,0);
- done |= fcsubs(&s,subs);
- if (n)
- fprintf(f,"%5d ",first);
- if (f == stdout)
- {
- niceprintf(s,f);
- putc('\n',f);
- }
- else
- fprintf(f,"%s\n",s);
- node = (r) ? node->last : node->next;
- (r) ? first-- : first++;
- }
- if (f != stdout)
- fclose(f);
- if (!done)
- {
- zerrnam("fc","no substitutions performed");
- return 1;
- }
- return 0;
-}
-
-/* perform old=new substituion */
-
-int fcsubs(char **sp,table tab)
-{
-Node n;
-char *s1,*s2,*s3,*s4,*s = *sp,*s5;
-int subbed = 0;
-
- for (n = tab->first; n; )
- {
- s1 = n->dat;
- n = n->next;
- s2 = n->dat;
- n = n->next;
- s5 = s;
- while (s3 = (char *) strstr(s5,s1))
- {
- s4 = zalloc(1+(s3-s)+strlen(s2)+strlen(s3+strlen(s1)));
- strncpy(s4,s,s3-s);
- s4[s3-s] = '\0';
- strcat(s4,s2);
- s5 = s4+strlen(s4);
- strcat(s4,s3+strlen(s1));
- free(s);
- s = s4;
- subbed = 1;
- }
- }
- *sp = s;
- return subbed;
-}
-
-int fcedit(char *ename,char *fn)
-{
- if (!strcmp(ename,"-"))
- return 1;
- return !zyztem(ename,fn);
-}
-
-int disown(comm comm)
-{
-char *str;
-int t0;
-static struct jobnode zero;
-
- while (str = getnode(comm->args))
- {
- t0 = getjob(str,"disown");
- if (t0 == -1)
- return 1;
- jobtab[t0] = zero;
- }
- return 0;
-}
-
-int function(comm comm)
-{
- if (full(comm->args))
- {
- zerrnam("function","too many arguments");
- return 1;
- }
- listhtable(shfunchtab,(void (*)(char *,char *)) pshfunc);
- return 0;
-}
-
-int (*funcs[])(comm) = {
- echo,zexit,logout,Unset,dirs,
- Alias,cd,which,popd,
- dot,pushd,shift,unhash,Break,
- colon,Glob,noglob,mostglob,unalias,
- fg,bg,jobs,Kill,export,
- Umask,cd,limit,unlimit,eval,
- unfunction,set,Brk,log,builtin,
- sched,let,fc,
- rehash,hash,disown,test,Read,
- integer,setopt,unsetopt,zreturn,function,
- test,
- NULL
- };
-char *funcnams[] = {
- "echo","exit","logout","unset","dirs",
- "alias","cd","which","popd",
- ".","pushd","shift","unhash","break",
- ":","glob","noglob","mostglob","unalias",
- "fg","bg","jobs","kill","export",
- "umask","chdir","limit","unlimit","eval",
- "unfunction","set","brk","log","builtin",
- "sched","let","fc",
- "rehash","hash","disown","test","read",
- "integer","setopt","unsetopt","return","function",
- "["
- };
-
-int builtin(comm comm)
-{
-char *s;
-int t0;
-
- s = getnode(comm->args);
- if (!s)
- {
- zerrnam("builtin","not enough arguments");
- return 1;
- }
- for (t0 = 0; funcs[t0]; t0++)
- if (!strcmp(funcnams[t0],s))
- break;
- if (!funcs[t0])
- {
- zerrnam("builtin","no such builtin: %s",s);
- return 1;
- }
- return (funcs[t0])(comm);
-}
-
-/* add builtins to the command hash table */
-
-void addintern(htable ht)
-{
-int (**ptr)(comm);
-struct chnode *ch;
-char **nam;
-
- for (ptr = funcs, nam = funcnams; *ptr; ptr++,nam++)
- {
- ch = alloc(sizeof(struct chnode));
- ch->type = BUILTIN;
- ch->u.func = *ptr;
- addhnode(strdup(*nam),ch,ht,freechnode);
- }
-}
-
-/* get the time of login/logout for WATCH */
-
-static time_t getlogtime(struct utmp *u,int inout)
-{
-FILE *in;
-struct utmp uu;
-int first = 1;
-
- if (inout)
- return u->ut_time;
- if (!(in = fopen(WTMP_FILE,"r")))
- return time(NULL);
- fseek(in,0,2);
- do
- {
- if (fseek(in,((first) ? -1 : -2)*sizeof(struct utmp),1))
- {
- fclose(in);
- return time(NULL);
- }
- first = 0;
- if (!fread(&uu,sizeof(struct utmp),1,in))
- {
- fclose(in);
- return time(NULL);
- }
- }
- while (memcmp(&uu,u,sizeof(struct utmp)));
- do
- if (!fread(&uu,sizeof(struct utmp),1,in))
- {
- fclose(in);
- return time(NULL);
- }
- while (strncmp(uu.ut_line,u->ut_line,8));
- fclose(in);
- return uu.ut_time;
-}
-
-/* print a login/logout event */
-
-static void watchlog2(int inout,struct utmp *u,char *fmt)
-{
-char *p,buf[40],*bf;
-int i;
-time_t timet;
-struct tm *tm = NULL;
-
- while (*fmt)
- if (*fmt != '%')
- putchar(*fmt++);
- else
- {
- fmt++;
- switch(*fmt++)
- {
- case 'n':
- printf("%.*s",8,u->ut_name);
- break;
- case 'a':
- printf("%s",(!inout) ? "logged off" : "logged on");
- break;
- case 'l':
- printf("%.*s",5,u->ut_line+3);
- break;
- case 'm':
- for (p = u->ut_host,i = 16; i && *p;i--,p++)
- {
- if (*p == '.' && !isdigit(p[1]))
- break;
- putchar(*p);
- }
- break;
- case 'M':
- printf("%.*s",16,u->ut_host);
- break;
- case 't':
- case '@':
- timet = getlogtime(u,inout);
- tm = localtime(&timet);
- strftime(buf,40,"%l:%M%p",tm);
- printf("%s",(*buf == ' ') ? buf+1 : buf);
- break;
- case 'T':
- timet = getlogtime(u,inout);
- tm = localtime(&timet);
- strftime(buf,40,"%k:%M",tm);
- printf("%s",buf);
- break;
- case 'w':
- timet = getlogtime(u,inout);
- tm = localtime(&timet);
- strftime(buf,40,"%a %e",tm);
- printf("%s",buf);
- break;
- case 'W':
- timet = getlogtime(u,inout);
- tm = localtime(&timet);
- strftime(buf,40,"%m/%d/%y",tm);
- printf("%s",buf);
- break;
- case 'D':
- timet = getlogtime(u,inout);
- tm = localtime(&timet);
- strftime(buf,40,"%y-%m-%d",tm);
- printf("%s",buf);
- break;
- case '%':
- putchar('%');
- break;
- case 'S':
- bf = buf;
- if (tgetstr("so",&bf))
- fputs(buf,stdout);
- break;
- case 's':
- bf = buf;
- if (tgetstr("se",&bf))
- fputs(buf,stdout);
- break;
- case 'B':
- bf = buf;
- if (tgetstr("md",&bf))
- fputs(buf,stdout);
- break;
- case 'b':
- bf = buf;
- if (tgetstr("me",&bf))
- fputs(buf,stdout);
- break;
- case 'U':
- bf = buf;
- if (tgetstr("us",&bf))
- fputs(buf,stdout);
- break;
- case 'u':
- bf = buf;
- if (tgetstr("ue",&bf))
- fputs(buf,stdout);
- break;
- default:
- putchar('%');
- putchar(fmt[-1]);
- break;
- }
- }
- putchar('\n');
-}
-
-/* check the list for login/logouts */
-
-static void watchlog(int inout,struct utmp *u,char *w,char *fmt)
-{
-char *v;
-
- if (!strcmp(w,"all"))
- {
- watchlog2(inout,u,fmt);
- return;
- }
- for(;;)
- if (v = strchr(w,':'))
- {
- if (!strncmp(u->ut_name,w,v-w))
- watchlog2(inout,u,fmt);
- w = v+1;
- }
- else
- {
- if (!strncmp(u->ut_name,w,8))
- watchlog2(inout,u,fmt);
- break;
- }
-}
-
-/* compare 2 utmp entries */
-
-static int ucmp(struct utmp *u,struct utmp *v)
-{
- if (u->ut_time == v->ut_time)
- return strncmp(u->ut_line,v->ut_line,8);
- return u->ut_time - v->ut_time;
-}
-
-/* initialize the user list */
-
-void readwtab(void)
-{
-struct utmp *uptr;
-int wtabmax = 32;
-FILE *in;
-
- wtabsz = 0;
- uptr = wtab = (struct utmp *) zalloc(wtabmax*sizeof(struct utmp));
- in = fopen(UTMP_FILE,"r");
- while (fread(uptr,sizeof(struct utmp),1,in))
- if (uptr->ut_host[0])
- {
- uptr++;
- if (++wtabsz == wtabmax)
- uptr = (wtab = (struct utmp *) realloc(wtab,(wtabmax*=2)*
- sizeof(struct utmp)))+wtabsz;
- }
- fclose(in);
- if (wtabsz)
- qsort(wtab,wtabsz,sizeof(struct utmp),ucmp);
-}
-
-/* check for login/logout events; executed before each prompt
- if WATCH is set */
-
-void watch(void)
-{
-char *s = getparm("WATCH");
-char *fmt = getparm("WATCHFMT");
-FILE *in;
-int utabsz = 0,utabmax = wtabsz+4,uct,wct;
-struct utmp *utab,*uptr,*wptr;
-
- holdintr();
- if (!fmt)
- fmt = "%n has %a %l from %m.";
- if (!wtab)
- {
- readwtab();
- noholdintr();
- return;
- }
- uptr = utab = (struct utmp *) zalloc(utabmax*sizeof(struct utmp));
- in = fopen(UTMP_FILE,"r");
- while (fread(uptr,sizeof *uptr,1,in))
- if (uptr->ut_host[0])
- {
- uptr++;
- if (++utabsz == utabmax)
- uptr = (utab = (struct utmp *) realloc(utab,(utabmax*=2)*
- sizeof(struct utmp)))+utabsz;
- }
- fclose(in);
- noholdintr();
- if (errflag)
- {
- free(utab);
- return;
- }
- if (utabsz)
- qsort(utab,utabsz,sizeof(struct utmp),ucmp);
-
- wct = wtabsz; uct = utabsz;
- uptr = utab; wptr = wtab;
- if (errflag)
- {
- free(utab);
- return;
- }
- while ((uct || wct) && !errflag)
- if (!uct || (wct && ucmp(uptr,wptr) > 0))
- wct--,watchlog(0,wptr++,s,fmt);
- else if (!wct || (uct && ucmp(uptr,wptr) < 0))
- uct--,watchlog(1,uptr++,s,fmt);
- else
- uptr++,wptr++,wct--,uct--;
- free(wtab);
- wtab = utab;
- wtabsz = utabsz;
- fflush(stdout);
-}
-
End of builtin.c
echo builtin.pro 1>&2
sed 's/^-//' >builtin.pro <<'End of builtin.pro'
-int echo(comm comm);
-void pdstack(void);
-int zexit(comm comm);
-int zreturn(comm comm);
-int logout(comm comm);
-int Unset(comm comm);
-int set(comm comm);
-int setopt(comm comm);
-int unsetopt(comm comm);
-int csetopt(comm comm,int isun);
-void pparm(char *s,struct pmnode *t);
-int dirs(comm comm);
-void listhtable(htable ht,void (*func)(char *,char *));
-void palias(char *s,struct anode *t);
-void pshfunc(char *s,list l);
-void niceprint(char *s);
-void niceprintf(char *s,FILE *f);
-char *buildline(table t);
-int Alias(comm comm);
-int cd(comm comm);
-int dot(comm comm);
-int Umask(comm comm);
-int which(comm comm);
-int popd(comm comm);
-int pushd(comm comm);
-int chcd(char *cnam,char *cd);
-int shift(comm comm);
-int unhash(comm comm);
-int rehash(comm comm);
-int hash(comm comm);
-int Break(comm comm);
-int colon(comm comm);
-int Glob(comm comm);
-int noglob(comm comm);
-int mostglob(comm comm);
-int unfunction(comm comm);
-int unalias(comm comm);
-int prefix(char *s,char *t);
-int getjob(char *s,char *prog);
-int fg(comm comm);
-int bg(comm comm);
-int jobs(comm comm);
-int Kill(comm comm);
-int export(comm comm);
-int integer(comm comm);
-int limit(comm comm);
-int unlimit(comm comm);
-void showlimits(int hard,int lim);
-int sched(comm comm);
-int eval(comm comm);
-int Brk(comm comm);
-int log(comm comm);
-int let(comm comm);
-int Read(comm comm);
-int fc(comm comm);
-int fcgetcomm(char *s);
-int fclist(FILE *f,int n,int r,int first,int last,table subs);
-int fcsubs(char **sp,table tab);
-int fcedit(char *ename,char *fn);
-int disown(comm comm);
-int function(comm comm);
-int builtin(comm comm);
-void addintern(htable ht);
-void readwtab(void);
-void watch(void);
End of builtin.pro
echo config.h 1>&2
sed 's/^-//' >config.h <<'End of config.h'
-/*
-
- config.h - configuration file
-
- This file is part of zsh, the Z shell.
-
- zsh is free software; no one can prevent you from reading the source
- code, or giving it to someone else.
- This file is copyrighted under the GNU General Public License, which
- can be found in the file called COPYING.
-
- Copyright (C) 1990 Paul Falstad
-
- zsh is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts
- responsibility to anyone for the consequences of using it or for
- whether it serves any particular purpose or works at all, unless he
- says so in writing. Refer to the GNU General Public License
- for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- zsh, but only under the conditions described in the GNU General Public
- License. A copy of this license is supposed to have been given to you
- along with zsh so you can know your rights and responsibilities.
- It should be in a file named COPYING.
-
- Among other things, the copyright notice and this notice must be
- preserved on all copies.
-
-*/
-
-/* define this if you have WAITPID */
-
-#define WAITPID
-
-/* define if the return type of signal handlers is int */
-
-/* #define INTHANDTYPE */
-
-/* the return type of handlers */
-
-#define HANDTYPE void
-
-/* define this if you have putenv */
-
-#define PUTENV
-
-/* define this if you have strstr */
-
-#define STRSTR
-
-/* define this if you have strftime */
-
-/* #define STRFTIME */
-
-/* define if you have struct termios, else struct sgttyb */
-
-#define TERMIOS
-
-#include "config.local.h"
-
End of config.h
echo config.local.h 1>&2
sed 's/^-//' >config.local.h <<'End of config.local.h'
-/*
-
- config.local.h - local machine configuration file
-
- This file is part of zsh, the Z shell.
-
- zsh is free software; no one can prevent you from reading the source
- code, or giving it to someone else.
- This file is copyrighted under the GNU General Public License, which
- can be found in the file called COPYING.
-
- Copyright (C) 1990 Paul Falstad
-
- zsh is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts
- responsibility to anyone for the consequences of using it or for
- whether it serves any particular purpose or works at all, unless he
- says so in writing. Refer to the GNU General Public License
- for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- zsh, but only under the conditions described in the GNU General Public
- License. A copy of this license is supposed to have been given to you
- along with zsh so you can know your rights and responsibilities.
- It should be in a file named COPYING.
-
- Among other things, the copyright notice and this notice must be
- preserved on all copies.
-
-*/
-
-/* a string corresponding to the host type */
-
-#define HOSTTYP "sun4"
-
-/* define if you prefer "suspended" to "stopped" */
-
-#define USE_SUSPENDED
-
-/* the path of zsh in the file system */
-
-#define MYSELF "/usr/princeton/bin/zsh"
-
-/* the default editor for the fc builtin */
-
-#define DEFFCEDIT "/usr/ucb/vi"
-
-/* the file to source whenever zsh is run; if undefined, don't source
- anything */
-
-#define GLOBALZSHRC "/etc/zshrc"
-
-/* the file to source whenever zsh is run as a login shell; if
- undefined, don't source anything */
-
-#define GLOBALZLOGIN "/etc/zlogin"
-
-/* the default HISTSIZE */
-
-#define DEFAULT_HISTSIZE 128
-
-/* the path of utmp */
-
-#define UTMP_FILE "/etc/utmp"
-
-/* the path of wtmp */
-
-#define WTMP_FILE "/var/adm/wtmp"
-
-/* define if you have problems with job control or tty modes.
- gcc-cpp does not seem to handle ioctls correctly. */
-
-/*#define BUGGY_GCC*/
-
-/* define if you like interactive comments */
-
-/*#define INTERACTIVE_COMMENTS*/
-
-/* define if you want warnings about nonexistent path components */
-
-#define PATH_WARNINGS
-
End of config.local.h
echo exec.c 1>&2
sed 's/^-//' >exec.c <<'End of exec.c'
-/*
-
- exec.c - command execution
-
- This file is part of zsh, the Z shell.
-
- zsh is free software; no one can prevent you from reading the source
- code, or giving it to someone else.
- This file is copyrighted under the GNU General Public License, which
- can be found in the file called COPYING.
-
- Copyright (C) 1990 Paul Falstad
-
- zsh is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts
- responsibility to anyone for the consequences of using it or for
- whether it serves any particular purpose or works at all, unless he
- says so in writing. Refer to the GNU General Public License
- for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- zsh, but only under the conditions described in the GNU General Public
- License. A copy of this license is supposed to have been given to you
- along with zsh so you can know your rights and responsibilities.
- It should be in a file named COPYING.
-
- Among other things, the copyright notice and this notice must be
- preserved on all copies.
-
-*/
-
-#include "zsh.h"
-#include "funcs.h"
-#include <sys/errno.h>
-#include <sys/dir.h>
-
-#define execerr() { if (forked) exit(1); freecmd(comm); \
- closemnodes(mfds); errflag = 1; return; }
-#define magicerr() { if (magic) putc('\n',stderr); errflag = 1; }
-
-/* execute a string */
-
-void execstring(char *s)
-{
-list l;
-
- hungets(strdup("\n"));
- hungets(s);
- strinbeg();
- if (!(l = parlist(1)))
- {
- strinend();
- hflush();
- return;
- }
- if (peek != EOF && peek != EMPTY)
- {
- strinend();
- hflush();
- return;
- }
- strinend();
- execlist(l);
-}
-
-/* duplicate a list and run it */
-
-void newrunlist(list l)
-{
-list a = duplist(l); runlist(a);
-}
-
-/* fork and set limits */
-
-int phork(void)
-{
-int pid = fork(),t0;
-
- if (pid == -1)
- {
- zerr("fork failed: %e",errno);
- return -1;
- }
- if (!pid)
- for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
- setrlimit(t0,limits+t0);
- return pid;
-}
-
-/* execute a current shell command */
-
-void execcursh(comm comm)
-{
- runlist(comm->left);
- comm->left = NULL;
-}
-
-/* execve an external command */
-
-void execute(char *arg0,table args)
-{
-char **argv;
-char *z,*s,buf[MAXPATHLEN],buf2[MAXPATHLEN];
-struct chnode *cn;
-int t0,tl,ee = 0;
-
-#define zexecve(X,Y,Z) {execve(z=(X),Y,Z);\
- if(errno!=ENOENT){ee = errno;strcpy(buf2,buf);}}
-
- cn = gethnode(arg0,chtab);
- if (s = getenv("STTY"))
- zyztem("stty",s);
- if (z = getenv("ARGV0"))
- z = strdup(z);
- else
- z = arg0;
- argv = makecline(z,args);
- fixsigs();
- if (cn)
- {
- if (cn->type == EXCMD_POSTDOT)
- {zexecve(arg0,argv,environ);}
- {zexecve(cn->u.nam,argv,environ);}
- }
- for (s = arg0; *s; s++)
- if (*s == '/')
- {
- execve(arg0,argv,environ);
- zerr("%e: %s",errno,arg0);
- _exit(1);
- }
- for (t0 = pathct; t0; t0--,path++)
- if (**path == '.')
- {zexecve(arg0,argv,environ);}
- else
- {
- tl = strlen(*path);
- strcpy(buf,*path);
- buf[tl] = '/';
- if (strlen(arg0)+strlen(buf)+1 >= MAXPATHLEN)
- {
- zerr("command too long: %s",arg0);
- _exit(1);
- }
- strcpy(buf+tl+1,arg0);
- {zexecve(buf,argv,environ);}
- }
- if (ee)
- {
- z = buf2;
- errno = ee;
- goto errs;
- }
- zerr("command not found: %s",arg0);
- _exit(1);
-errs:
- zerr("%e: %s",errno,z);
- _exit(1);
-}
-
-#define try(X) { if (!access(X,X_OK)) return strdup(X); }
-
-/* get the pathname of a command */
-
-char *findcmd(char *arg0)
-{
-char *s,buf[MAXPATHLEN];
-int t0,tl;
-struct chnode *cn = gethnode(arg0,chtab);
-char **pp = path;
-
- if (cn)
- {
- if (cn->type == EXCMD_POSTDOT)
- {
- strcpy(buf,"./");
- strcat(buf,arg0);
- try(buf);
- }
- try(cn->u.nam);
- }
- for (s = arg0; *s; s++)
- if (*s == '/')
- {
- try(arg0);
- goto failed;
- }
- for (t0 = pathct; t0; t0--,pp++)
- if (**pp == '.')
- {
- strcpy(buf,"./");
- strcat(buf,arg0);
- try(buf);
- }
- else
- {
- tl = strlen(*pp);
- strcpy(buf,*pp);
- buf[tl] = '/';
- strcpy(buf+tl+1,arg0);
- try(buf);
- }
-failed:
- return NULL;
-}
-
-void execlist(list list)
-{
- execlist1(list);
- freelist(list);
-}
-
-void execlist1(list list)
-{
- if (breaks)
- return;
- switch(list->type)
- {
- case SYNC:
- case ASYNC:
- execlist2(list->left,list->type,!list->right);
- if (sigtrapped[SIGDEBUG])
- dotrap(SIGDEBUG);
- if (sigtrapped[SIGERR] && lastval)
- dotrap(SIGERR);
- if (list->right && !retflag)
- execlist1(list->right);
- break;
- }
-}
-
-void execlist2(list2 list,int type,int last1)
-{
- switch(list->type)
- {
- case END:
- execpline(list,type,last1);
- break;
- case ORNEXT:
- if (!execpline(list,SYNC,0))
- execlist2(list->right,type,last1);
- break;
- case ANDNEXT:
- if (execpline(list,SYNC,0))
- execlist2(list->right,type,last1);
- break;
- }
-}
-
-int execpline(list2 l,int how,int last1)
-{
-int ipipe[2] = {0,0},opipe[2] = {0,0};
-
- sigblock(sigmask(SIGCHLD));
- curjob = getfreejob();
- initjob(l->flags);
- if (l->flags & PFLAG_COPROC)
- {
- how = ASYNC;
- mpipe(ipipe);
- mpipe(opipe);
- if (spin)
- {
- close(spin);
- close(spout);
- }
- spin = ipipe[0];
- spout = opipe[1];
- }
- execpline2(l->left,how,opipe[0],ipipe[1],last1);
- if (how == ASYNC)
- {
- spawnjob();
- sigsetmask(0);
- return 1;
- }
- else
- {
- waitjobs();
- sigsetmask(0);
- if (l->flags & PFLAG_NOT)
- lastval = !lastval;
- return !lastval;
- }
-}
-
-void execpline2(pline pline,int how,int input,int output,int last1)
-{
-int pid;
-int pipes[2];
-
- if (breaks)
- return;
- if (!pline)
- return;
- if (pline->type == END)
- {
- execcomm(pline->left,input,output,how==ASYNC,last1);
- pline->left = NULL;
- }
- else
- {
- mpipe(pipes);
-
- /* if we are doing "foo | bar" where foo is a current
- shell command, do foo in the current shell and do
- the rest of the pipeline in a subshell. */
-
- if (pline->left->type >= CURSH && how == SYNC)
- {
- if (!(pid = fork()))
- {
---cut here---cut here---cut here---
More information about the Alt.sources
mailing list