MFS: No longer needed in PicoBSD 0.44

This commit is contained in:
roger 1999-06-15 11:40:13 +00:00
parent 008e15781e
commit 1252b4b671
71 changed files with 0 additions and 19007 deletions

View File

@ -1,80 +0,0 @@
#!/bin/sh -
# $Id: rc.network.pl,v 1.1.1.1 1998/08/27 17:38:42 abial Exp $
network_pass1() {
echo -n 'Wstepna konfiguracja sieci:'
# Set the host name if it is not already set
if [ -z "`hostname -s`" ] ; then
hostname $hostname
echo ' hostname'
fi
# Set up all the network interfaces, calling startup scripts if needed
for ifn in ${network_interfaces}; do
if [ -e /etc/start_if.${ifn} ]; then
. /etc/start_if.${ifn}
fi
# Do the primary ifconfig if specified
eval ifconfig_args=\$ifconfig_${ifn}
if [ -n "${ifconfig_args}" ] ; then
ifconfig ${ifn} ${ifconfig_args}
fi
# Check to see if aliases need to be added
alias=0
while :
do
eval ifconfig_args=\$ifconfig_${ifn}_alias${alias}
if [ -n "${ifconfig_args}" ]; then
ifconfig ${ifn} ${ifconfig_args} alias
alias=`expr ${alias} + 1`
else
break;
fi
done
ifconfig ${ifn}
done
# Load the filters if required
if [ -n "$firewall_enable" -a -f /etc/rc.firewall -a \
"x$firewall_enable" = "xYES" ] ; then
. /etc/rc.firewall
echo "Zaladowano reguly filtrujace do firewalla."
else
echo "UWAGA: system posiada wbudowany modul firewalla, ale zadne reguly"
echo " filtrujace nie zostaly zaladowane."
echo " Wszystkie rodzaje ruchu IP sa dozwolone."
fi
# Configure routing
if [ "x$defaultrouter" != "xNO" ] ; then
static_routes="default ${static_routes}"
route_default="default ${defaultrouter}"
fi
# Set up any static routes. This should be done before router discovery.
if [ "x${static_routes}" != "x" ]; then
for i in ${static_routes}; do
eval route_args=\$route_${i}
route add ${route_args}
done
fi
echo -n 'Dodatkowe opcje routingu:'
if [ -n "$tcp_extensions" -a "x$tcp_extensions" != "xYES" ] ; then
echo -n ' tcp_extensions=NO'
sysctl -w net.inet.tcp.rfc1323=0 >/dev/null 2>&1
sysctl -w net.inet.tcp.rfc1644=0 >/dev/null 2>&1
fi
if [ "X$gateway_enable" = X"YES" ]; then
echo -n ' IP_gateway=YES'
sysctl -w net.inet.ip.forwarding=1 >/dev/null 2>&1
fi
if [ "X$arpproxy_all" = X"YES" ]; then
echo -n ' wlaczam ARP_PROXY_ALL: '
sysctl -w net.link.ether.inet.proxyall=1 2>&1
fi
echo '.'
network_pass1_done=YES # Let future generations know we made it.
}
network_pass2() {
network_pass2_done=YES
}
network_pass3() {
network_pass3_done=YES
}

View File

@ -1,44 +0,0 @@
# $NetBSD: Makefile,v 1.33 1997/07/04 21:40:55 christos Exp $
# @(#)Makefile 8.4 (Berkeley) 5/5/95
WARNS= 1
PROG= sh
SHSRCS= alias.c cd.c echo.c error.c eval.c exec.c expand.c \
histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \
mystring.c options.c parser.c redir.c show.c trap.c output.c var.c
GENSRCS=arith.c arith_lex.c builtins.c builtins.h init.c nodes.c nodes.h \
syntax.c syntax.h token.h
SRCS= ${SHSRCS} ${GENSRCS}
LDADD+= -ll -ledit -ltermcap
DPADD+= ${LIBL} ${LIBEDIT} ${LIBTERMCAP}
LFLAGS= -8 # 8-bit lex scanner for arithmetic
CFLAGS+=-DSHELL -I. -I${.CURDIR}
.PATH: ${.CURDIR}/bltin ${.CURDIR}/../../usr.bin/printf
CLEANFILES+= mkinit mknodes mksyntax
CLEANFILES+= mkinit.o mknodes.o mksyntax.o
CLEANFILES+= ${GENSRCS} y.tab.h
token.h: mktokens
sh ${.CURDIR}/mktokens
builtins.c builtins.h: mkbuiltins builtins.def
cd ${.CURDIR}; sh mkbuiltins ${.OBJDIR}
init.c: mkinit ${SHSRCS}
./mkinit ${.ALLSRC:S/^mkinit$//}
nodes.c nodes.h: mknodes nodetypes nodes.c.pat
./mknodes ${.CURDIR}/nodetypes ${.CURDIR}/nodes.c.pat
syntax.c syntax.h: mksyntax
./mksyntax
.include <bsd.prog.mk>
${OBJS}: builtins.h nodes.h syntax.h token.h

View File

@ -1,357 +0,0 @@
# $NetBSD: TOUR,v 1.8 1996/10/16 14:24:56 christos Exp $
# @(#)TOUR 8.1 (Berkeley) 5/31/93
NOTE -- This is the original TOUR paper distributed with ash and
does not represent the current state of the shell. It is provided anyway
since it provides helpful information for how the shell is structured,
but be warned that things have changed -- the current shell is
still under development.
================================================================
A Tour through Ash
Copyright 1989 by Kenneth Almquist.
DIRECTORIES: The subdirectory bltin contains commands which can
be compiled stand-alone. The rest of the source is in the main
ash directory.
SOURCE CODE GENERATORS: Files whose names begin with "mk" are
programs that generate source code. A complete list of these
programs is:
program intput files generates
------- ------------ ---------
mkbuiltins builtins builtins.h builtins.c
mkinit *.c init.c
mknodes nodetypes nodes.h nodes.c
mksignames - signames.h signames.c
mksyntax - syntax.h syntax.c
mktokens - token.h
bltin/mkexpr unary_op binary_op operators.h operators.c
There are undoubtedly too many of these. Mkinit searches all the
C source files for entries looking like:
INIT {
x = 1; /* executed during initialization */
}
RESET {
x = 2; /* executed when the shell does a longjmp
back to the main command loop */
}
SHELLPROC {
x = 3; /* executed when the shell runs a shell procedure */
}
It pulls this code out into routines which are when particular
events occur. The intent is to improve modularity by isolating
the information about which modules need to be explicitly
initialized/reset within the modules themselves.
Mkinit recognizes several constructs for placing declarations in
the init.c file.
INCLUDE "file.h"
includes a file. The storage class MKINIT makes a declaration
available in the init.c file, for example:
MKINIT int funcnest; /* depth of function calls */
MKINIT alone on a line introduces a structure or union declara-
tion:
MKINIT
struct redirtab {
short renamed[10];
};
Preprocessor #define statements are copied to init.c without any
special action to request this.
INDENTATION: The ash source is indented in multiples of six
spaces. The only study that I have heard of on the subject con-
cluded that the optimal amount to indent is in the range of four
to six spaces. I use six spaces since it is not too big a jump
from the widely used eight spaces. If you really hate six space
indentation, use the adjind (source included) program to change
it to something else.
EXCEPTIONS: Code for dealing with exceptions appears in
exceptions.c. The C language doesn't include exception handling,
so I implement it using setjmp and longjmp. The global variable
exception contains the type of exception. EXERROR is raised by
calling error. EXINT is an interrupt. EXSHELLPROC is an excep-
tion which is raised when a shell procedure is invoked. The pur-
pose of EXSHELLPROC is to perform the cleanup actions associated
with other exceptions. After these cleanup actions, the shell
can interpret a shell procedure itself without exec'ing a new
copy of the shell.
INTERRUPTS: In an interactive shell, an interrupt will cause an
EXINT exception to return to the main command loop. (Exception:
EXINT is not raised if the user traps interrupts using the trap
command.) The INTOFF and INTON macros (defined in exception.h)
provide uninterruptable critical sections. Between the execution
of INTOFF and the execution of INTON, interrupt signals will be
held for later delivery. INTOFF and INTON can be nested.
MEMALLOC.C: Memalloc.c defines versions of malloc and realloc
which call error when there is no memory left. It also defines a
stack oriented memory allocation scheme. Allocating off a stack
is probably more efficient than allocation using malloc, but the
big advantage is that when an exception occurs all we have to do
to free up the memory in use at the time of the exception is to
restore the stack pointer. The stack is implemented using a
linked list of blocks.
STPUTC: If the stack were contiguous, it would be easy to store
strings on the stack without knowing in advance how long the
string was going to be:
p = stackptr;
*p++ = c; /* repeated as many times as needed */
stackptr = p;
The folloing three macros (defined in memalloc.h) perform these
operations, but grow the stack if you run off the end:
STARTSTACKSTR(p);
STPUTC(c, p); /* repeated as many times as needed */
grabstackstr(p);
We now start a top-down look at the code:
MAIN.C: The main routine performs some initialization, executes
the user's profile if necessary, and calls cmdloop. Cmdloop is
repeatedly parses and executes commands.
OPTIONS.C: This file contains the option processing code. It is
called from main to parse the shell arguments when the shell is
invoked, and it also contains the set builtin. The -i and -j op-
tions (the latter turns on job control) require changes in signal
handling. The routines setjobctl (in jobs.c) and setinteractive
(in trap.c) are called to handle changes to these options.
PARSING: The parser code is all in parser.c. A recursive des-
cent parser is used. Syntax tables (generated by mksyntax) are
used to classify characters during lexical analysis. There are
three tables: one for normal use, one for use when inside single
quotes, and one for use when inside double quotes. The tables
are machine dependent because they are indexed by character vari-
ables and the range of a char varies from machine to machine.
PARSE OUTPUT: The output of the parser consists of a tree of
nodes. The various types of nodes are defined in the file node-
types.
Nodes of type NARG are used to represent both words and the con-
tents of here documents. An early version of ash kept the con-
tents of here documents in temporary files, but keeping here do-
cuments in memory typically results in significantly better per-
formance. It would have been nice to make it an option to use
temporary files for here documents, for the benefit of small
machines, but the code to keep track of when to delete the tem-
porary files was complex and I never fixed all the bugs in it.
(AT&T has been maintaining the Bourne shell for more than ten
years, and to the best of my knowledge they still haven't gotten
it to handle temporary files correctly in obscure cases.)
The text field of a NARG structure points to the text of the
word. The text consists of ordinary characters and a number of
special codes defined in parser.h. The special codes are:
CTLVAR Variable substitution
CTLENDVAR End of variable substitution
CTLBACKQ Command substitution
CTLBACKQ|CTLQUOTE Command substitution inside double quotes
CTLESC Escape next character
A variable substitution contains the following elements:
CTLVAR type name '=' [ alternative-text CTLENDVAR ]
The type field is a single character specifying the type of sub-
stitution. The possible types are:
VSNORMAL $var
VSMINUS ${var-text}
VSMINUS|VSNUL ${var:-text}
VSPLUS ${var+text}
VSPLUS|VSNUL ${var:+text}
VSQUESTION ${var?text}
VSQUESTION|VSNUL ${var:?text}
VSASSIGN ${var=text}
VSASSIGN|VSNUL ${var=text}
In addition, the type field will have the VSQUOTE flag set if the
variable is enclosed in double quotes. The name of the variable
comes next, terminated by an equals sign. If the type is not
VSNORMAL, then the text field in the substitution follows, ter-
minated by a CTLENDVAR byte.
Commands in back quotes are parsed and stored in a linked list.
The locations of these commands in the string are indicated by
CTLBACKQ and CTLBACKQ+CTLQUOTE characters, depending upon whether
the back quotes were enclosed in double quotes.
The character CTLESC escapes the next character, so that in case
any of the CTL characters mentioned above appear in the input,
they can be passed through transparently. CTLESC is also used to
escape '*', '?', '[', and '!' characters which were quoted by the
user and thus should not be used for file name generation.
CTLESC characters have proved to be particularly tricky to get
right. In the case of here documents which are not subject to
variable and command substitution, the parser doesn't insert any
CTLESC characters to begin with (so the contents of the text
field can be written without any processing). Other here docu-
ments, and words which are not subject to splitting and file name
generation, have the CTLESC characters removed during the vari-
able and command substitution phase. Words which are subject
splitting and file name generation have the CTLESC characters re-
moved as part of the file name phase.
EXECUTION: Command execution is handled by the following files:
eval.c The top level routines.
redir.c Code to handle redirection of input and output.
jobs.c Code to handle forking, waiting, and job control.
exec.c Code to to path searches and the actual exec sys call.
expand.c Code to evaluate arguments.
var.c Maintains the variable symbol table. Called from expand.c.
EVAL.C: Evaltree recursively executes a parse tree. The exit
status is returned in the global variable exitstatus. The alter-
native entry evalbackcmd is called to evaluate commands in back
quotes. It saves the result in memory if the command is a buil-
tin; otherwise it forks off a child to execute the command and
connects the standard output of the child to a pipe.
JOBS.C: To create a process, you call makejob to return a job
structure, and then call forkshell (passing the job structure as
an argument) to create the process. Waitforjob waits for a job
to complete. These routines take care of process groups if job
control is defined.
REDIR.C: Ash allows file descriptors to be redirected and then
restored without forking off a child process. This is accom-
plished by duplicating the original file descriptors. The redir-
tab structure records where the file descriptors have be dupli-
cated to.
EXEC.C: The routine find_command locates a command, and enters
the command in the hash table if it is not already there. The
third argument specifies whether it is to print an error message
if the command is not found. (When a pipeline is set up,
find_command is called for all the commands in the pipeline be-
fore any forking is done, so to get the commands into the hash
table of the parent process. But to make command hashing as
transparent as possible, we silently ignore errors at that point
and only print error messages if the command cannot be found
later.)
The routine shellexec is the interface to the exec system call.
EXPAND.C: Arguments are processed in three passes. The first
(performed by the routine argstr) performs variable and command
substitution. The second (ifsbreakup) performs word splitting
and the third (expandmeta) performs file name generation. If the
"/u" directory is simulated, then when "/u/username" is replaced
by the user's home directory, the flag "didudir" is set. This
tells the cd command that it should print out the directory name,
just as it would if the "/u" directory were implemented using
symbolic links.
VAR.C: Variables are stored in a hash table. Probably we should
switch to extensible hashing. The variable name is stored in the
same string as the value (using the format "name=value") so that
no string copying is needed to create the environment of a com-
mand. Variables which the shell references internally are preal-
located so that the shell can reference the values of these vari-
ables without doing a lookup.
When a program is run, the code in eval.c sticks any environment
variables which precede the command (as in "PATH=xxx command") in
the variable table as the simplest way to strip duplicates, and
then calls "environment" to get the value of the environment.
There are two consequences of this. First, if an assignment to
PATH precedes the command, the value of PATH before the assign-
ment must be remembered and passed to shellexec. Second, if the
program turns out to be a shell procedure, the strings from the
environment variables which preceded the command must be pulled
out of the table and replaced with strings obtained from malloc,
since the former will automatically be freed when the stack (see
the entry on memalloc.c) is emptied.
BUILTIN COMMANDS: The procedures for handling these are scat-
tered throughout the code, depending on which location appears
most appropriate. They can be recognized because their names al-
ways end in "cmd". The mapping from names to procedures is
specified in the file builtins, which is processed by the mkbuil-
tins command.
A builtin command is invoked with argc and argv set up like a
normal program. A builtin command is allowed to overwrite its
arguments. Builtin routines can call nextopt to do option pars-
ing. This is kind of like getopt, but you don't pass argc and
argv to it. Builtin routines can also call error. This routine
normally terminates the shell (or returns to the main command
loop if the shell is interactive), but when called from a builtin
command it causes the builtin command to terminate with an exit
status of 2.
The directory bltins contains commands which can be compiled in-
dependently but can also be built into the shell for efficiency
reasons. The makefile in this directory compiles these programs
in the normal fashion (so that they can be run regardless of
whether the invoker is ash), but also creates a library named
bltinlib.a which can be linked with ash. The header file bltin.h
takes care of most of the differences between the ash and the
stand-alone environment. The user should call the main routine
"main", and #define main to be the name of the routine to use
when the program is linked into ash. This #define should appear
before bltin.h is included; bltin.h will #undef main if the pro-
gram is to be compiled stand-alone.
CD.C: This file defines the cd and pwd builtins. The pwd com-
mand runs /bin/pwd the first time it is invoked (unless the user
has already done a cd to an absolute pathname), but then
remembers the current directory and updates it when the cd com-
mand is run, so subsequent pwd commands run very fast. The main
complication in the cd command is in the docd command, which
resolves symbolic links into actual names and informs the user
where the user ended up if he crossed a symbolic link.
SIGNALS: Trap.c implements the trap command. The routine set-
signal figures out what action should be taken when a signal is
received and invokes the signal system call to set the signal ac-
tion appropriately. When a signal that a user has set a trap for
is caught, the routine "onsig" sets a flag. The routine dotrap
is called at appropriate points to actually handle the signal.
When an interrupt is caught and no trap has been set for that
signal, the routine "onint" in error.c is called.
OUTPUT: Ash uses it's own output routines. There are three out-
put structures allocated. "Output" represents the standard out-
put, "errout" the standard error, and "memout" contains output
which is to be stored in memory. This last is used when a buil-
tin command appears in backquotes, to allow its output to be col-
lected without doing any I/O through the UNIX operating system.
The variables out1 and out2 normally point to output and errout,
respectively, but they are set to point to memout when appropri-
ate inside backquotes.
INPUT: The basic input routine is pgetc, which reads from the
current input file. There is a stack of input files; the current
input file is the top file on this stack. The code allows the
input to come from a string rather than a file. (This is for the
-c option and the "." and eval builtin commands.) The global
variable plinno is saved and restored when files are pushed and
popped from the stack. The parser routines store the number of
the current line in this variable.
DEBUGGING: If DEBUG is defined in shell.h, then the shell will
write debugging information to the file $HOME/trace. Most of
this is done using the TRACE macro, which takes a set of printf
arguments inside two sets of parenthesis. Example:
"TRACE(("n=%d0, n))". The double parenthesis are necessary be-
cause the preprocessor can't handle functions with a variable
number of arguments. Defining DEBUG also causes the shell to
generate a core dump if it is sent a quit signal. The tracing
code is in show.c.

View File

@ -1,267 +0,0 @@
/* $NetBSD: alias.c,v 1.9 1997/07/04 21:01:48 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: alias.c,v 1.9 1997/07/04 21:01:48 christos Exp $");
#endif
#endif /* not lint */
#include <stdlib.h>
#include "shell.h"
#include "input.h"
#include "output.h"
#include "error.h"
#include "memalloc.h"
#include "mystring.h"
#include "alias.h"
#include "options.h" /* XXX for argptr (should remove?) */
#define ATABSIZE 39
struct alias *atab[ATABSIZE];
STATIC void setalias __P((char *, char *));
STATIC int unalias __P((char *));
STATIC struct alias **hashalias __P((char *));
STATIC
void
setalias(name, val)
char *name, *val;
{
struct alias *ap, **app;
app = hashalias(name);
for (ap = *app; ap; ap = ap->next) {
if (equal(name, ap->name)) {
INTOFF;
ckfree(ap->val);
ap->val = savestr(val);
INTON;
return;
}
}
/* not found */
INTOFF;
ap = ckmalloc(sizeof (struct alias));
ap->name = savestr(name);
/*
* XXX - HACK: in order that the parser will not finish reading the
* alias value off the input before processing the next alias, we
* dummy up an extra space at the end of the alias. This is a crock
* and should be re-thought. The idea (if you feel inclined to help)
* is to avoid alias recursions. The mechanism used is: when
* expanding an alias, the value of the alias is pushed back on the
* input as a string and a pointer to the alias is stored with the
* string. The alias is marked as being in use. When the input
* routine finishes reading the string, it markes the alias not
* in use. The problem is synchronization with the parser. Since
* it reads ahead, the alias is marked not in use before the
* resulting token(s) is next checked for further alias sub. The
* H A C K is that we add a little fluff after the alias value
* so that the string will not be exhausted. This is a good
* idea ------- ***NOT***
*/
#ifdef notyet
ap->val = savestr(val);
#else /* hack */
{
int len = strlen(val);
ap->val = ckmalloc(len + 2);
memcpy(ap->val, val, len);
ap->val[len] = ' '; /* fluff */
ap->val[len+1] = '\0';
}
#endif
ap->next = *app;
*app = ap;
INTON;
}
STATIC int
unalias(name)
char *name;
{
struct alias *ap, **app;
app = hashalias(name);
for (ap = *app; ap; app = &(ap->next), ap = ap->next) {
if (equal(name, ap->name)) {
/*
* if the alias is currently in use (i.e. its
* buffer is being used by the input routine) we
* just null out the name instead of freeing it.
* We could clear it out later, but this situation
* is so rare that it hardly seems worth it.
*/
if (ap->flag & ALIASINUSE)
*ap->name = '\0';
else {
INTOFF;
*app = ap->next;
ckfree(ap->name);
ckfree(ap->val);
ckfree(ap);
INTON;
}
return (0);
}
}
return (1);
}
#ifdef mkinit
MKINIT void rmaliases __P((void));
SHELLPROC {
rmaliases();
}
#endif
void
rmaliases() {
struct alias *ap, *tmp;
int i;
INTOFF;
for (i = 0; i < ATABSIZE; i++) {
ap = atab[i];
atab[i] = NULL;
while (ap) {
ckfree(ap->name);
ckfree(ap->val);
tmp = ap;
ap = ap->next;
ckfree(tmp);
}
}
INTON;
}
struct alias *
lookupalias(name, check)
char *name;
int check;
{
struct alias *ap = *hashalias(name);
for (; ap; ap = ap->next) {
if (equal(name, ap->name)) {
if (check && (ap->flag & ALIASINUSE))
return (NULL);
return (ap);
}
}
return (NULL);
}
/*
* TODO - sort output
*/
int
aliascmd(argc, argv)
int argc;
char **argv;
{
char *n, *v;
int ret = 0;
struct alias *ap;
if (argc == 1) {
int i;
for (i = 0; i < ATABSIZE; i++)
for (ap = atab[i]; ap; ap = ap->next) {
if (*ap->name != '\0')
out1fmt("alias %s=%s\n", ap->name, ap->val);
}
return (0);
}
while ((n = *++argv) != NULL) {
if ((v = strchr(n+1, '=')) == NULL) /* n+1: funny ksh stuff */
if ((ap = lookupalias(n, 0)) == NULL) {
outfmt(out2, "alias: %s not found\n", n);
ret = 1;
} else
out1fmt("alias %s=%s\n", n, ap->val);
else {
*v++ = '\0';
setalias(n, v);
}
}
return (ret);
}
int
unaliascmd(argc, argv)
int argc;
char **argv;
{
int i;
while ((i = nextopt("a")) != '\0') {
if (i == 'a') {
rmaliases();
return (0);
}
}
for (i = 0; *argptr; argptr++)
i = unalias(*argptr);
return (i);
}
STATIC struct alias **
hashalias(p)
char *p;
{
unsigned int hashval;
hashval = *p << 4;
while (*p)
hashval+= *p++;
return &atab[hashval % ATABSIZE];
}

View File

@ -1,53 +0,0 @@
/* $NetBSD: alias.h,v 1.4 1995/05/11 21:28:42 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)alias.h 8.2 (Berkeley) 5/4/95
*/
#define ALIASINUSE 1
struct alias {
struct alias *next;
char *name;
char *val;
int flag;
};
struct alias *lookupalias __P((char *, int));
int aliascmd __P((int, char **));
int unaliascmd __P((int, char **));
void rmaliases __P((void));

View File

@ -1,41 +0,0 @@
/* $NetBSD: arith.h,v 1.2 1997/07/04 21:01:49 christos Exp $ */
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)arith.h 1.1 (Berkeley) 5/4/95
*/
int arith __P((char *));
int expcmd __P((int , char **));
void arith_lex_reset __P((void));
int yylex __P((void));

View File

@ -1,201 +0,0 @@
%{
/* $NetBSD: arith.y,v 1.8 1997/07/04 21:01:50 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: arith.y,v 1.8 1997/07/04 21:01:50 christos Exp $");
#endif
#endif /* not lint */
#include "arith.h"
#include "shell.h"
#include "error.h"
#include "output.h"
#include "memalloc.h"
char *arith_buf, *arith_startbuf;
void yyerror __P((char *));
int yyparse __P((void));
#ifdef TESTARITH
int main __P((int , char *[]));
int error __P((char *));
#endif
int
arith(s)
char *s;
{
long result;
arith_buf = arith_startbuf = s;
INTOFF;
result = yyparse();
arith_lex_reset(); /* reprime lex */
INTON;
return (result);
}
/*
* The exp(1) builtin.
*/
int
expcmd(argc, argv)
int argc;
char **argv;
{
char *p;
char *concat;
char **ap;
long i;
if (argc > 1) {
p = argv[1];
if (argc > 2) {
/*
* concatenate arguments
*/
STARTSTACKSTR(concat);
ap = argv + 2;
for (;;) {
while (*p)
STPUTC(*p++, concat);
if ((p = *ap++) == NULL)
break;
STPUTC(' ', concat);
}
STPUTC('\0', concat);
p = grabstackstr(concat);
}
} else
p = "";
i = arith(p);
out1fmt("%d\n", i);
return (! i);
}
/*************************/
#ifdef TEST_ARITH
#include <stdio.h>
main(argc, argv)
char *argv[];
{
printf("%d\n", exp(argv[1]));
}
error(s)
char *s;
{
fprintf(stderr, "exp: %s\n", s);
exit(1);
}
#endif
%}
%token ARITH_NUM ARITH_LPAREN ARITH_RPAREN
%left ARITH_OR
%left ARITH_AND
%left ARITH_BOR
%left ARITH_BXOR
%left ARITH_BAND
%left ARITH_EQ ARITH_NE
%left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
%left ARITH_LSHIFT ARITH_RSHIFT
%left ARITH_ADD ARITH_SUB
%left ARITH_MUL ARITH_DIV ARITH_REM
%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
%%
exp: expr = {
return ($1);
}
;
expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; }
| expr ARITH_OR expr = { $$ = $1 ? $1 : $3 ? $3 : 0; }
| expr ARITH_AND expr = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; }
| expr ARITH_BOR expr = { $$ = $1 | $3; }
| expr ARITH_BXOR expr = { $$ = $1 ^ $3; }
| expr ARITH_BAND expr = { $$ = $1 & $3; }
| expr ARITH_EQ expr = { $$ = $1 == $3; }
| expr ARITH_GT expr = { $$ = $1 > $3; }
| expr ARITH_GE expr = { $$ = $1 >= $3; }
| expr ARITH_LT expr = { $$ = $1 < $3; }
| expr ARITH_LE expr = { $$ = $1 <= $3; }
| expr ARITH_NE expr = { $$ = $1 != $3; }
| expr ARITH_LSHIFT expr = { $$ = $1 << $3; }
| expr ARITH_RSHIFT expr = { $$ = $1 >> $3; }
| expr ARITH_ADD expr = { $$ = $1 + $3; }
| expr ARITH_SUB expr = { $$ = $1 - $3; }
| expr ARITH_MUL expr = { $$ = $1 * $3; }
| expr ARITH_DIV expr = {
if ($3 == 0)
yyerror("division by zero");
$$ = $1 / $3;
}
| expr ARITH_REM expr = {
if ($3 == 0)
yyerror("division by zero");
$$ = $1 % $3;
}
| ARITH_NOT expr = { $$ = !($2); }
| ARITH_BNOT expr = { $$ = ~($2); }
| ARITH_SUB expr %prec ARITH_UNARYMINUS = { $$ = -($2); }
| ARITH_ADD expr %prec ARITH_UNARYPLUS = { $$ = $2; }
| ARITH_NUM
;
%%
void
yyerror(s)
char *s;
{
yyerrok;
yyclearin;
arith_lex_reset(); /* reprime lex */
error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
}

View File

@ -1,93 +0,0 @@
%{
/* $NetBSD: arith_lex.l,v 1.7 1997/07/04 21:01:51 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: arith_lex.l,v 1.7 1997/07/04 21:01:51 christos Exp $");
#endif
#endif /* not lint */
#include <unistd.h>
#include "y.tab.h"
#include "error.h"
#include "arith.h"
extern yylval;
extern char *arith_buf, *arith_startbuf;
#undef YY_INPUT
#define YY_INPUT(buf,result,max) \
result = (*buf = *arith_buf++) ? 1 : YY_NULL;
#define YY_NO_UNPUT
%}
%%
[ \t\n] { ; }
[0-9]+ { yylval = atol(yytext); return(ARITH_NUM); }
"(" { return(ARITH_LPAREN); }
")" { return(ARITH_RPAREN); }
"||" { return(ARITH_OR); }
"&&" { return(ARITH_AND); }
"|" { return(ARITH_BOR); }
"^" { return(ARITH_BXOR); }
"&" { return(ARITH_BAND); }
"==" { return(ARITH_EQ); }
"!=" { return(ARITH_NE); }
">" { return(ARITH_GT); }
">=" { return(ARITH_GE); }
"<" { return(ARITH_LT); }
"<=" { return(ARITH_LE); }
"<<" { return(ARITH_LSHIFT); }
">>" { return(ARITH_RSHIFT); }
"*" { return(ARITH_MUL); }
"/" { return(ARITH_DIV); }
"%" { return(ARITH_REM); }
"+" { return(ARITH_ADD); }
"-" { return(ARITH_SUB); }
"~" { return(ARITH_BNOT); }
"!" { return(ARITH_NOT); }
. { error("arith: syntax error: \"%s\"\n", arith_startbuf); }
%%
void
arith_lex_reset() {
YY_NEW_FILE;
}

View File

@ -1,78 +0,0 @@
/* $NetBSD: bltin.h,v 1.9 1997/07/04 21:02:29 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bltin.h 8.1 (Berkeley) 5/31/93
*/
/*
* This file is included by programs which are optionally built into the
* shell. If SHELL is defined, we try to map the standard UNIX library
* routines to ash routines using defines.
*/
#include "../shell.h"
#include "../mystring.h"
#ifdef SHELL
#include "../output.h"
#define stdout out1
#define stderr out2
#define printf out1fmt
#define putc(c, file) outc(c, file)
#define putchar(c) out1c(c)
#define fprintf outfmt
#define fputs outstr
#define fflush flushout
#define INITARGS(argv)
#define warnx(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a, b, c); \
error("%s", buf); \
}
#else
#undef NULL
#include <stdio.h>
#undef main
#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else
#endif
pointer stalloc __P((int));
void error __P((char *, ...));
int echocmd __P((int, char **));
extern char *commandname;

View File

@ -1,113 +0,0 @@
.\" $NetBSD: echo.1,v 1.8 1996/10/16 15:27:03 christos Exp $
.\"
.\" Copyright (c) 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" Kenneth Almquist.
.\" Copyright 1989 by Kenneth Almquist
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)echo.1 8.1 (Berkeley) 5/31/93
.\"
.Dd May 31, 1993
.Dt ECHO 1
.Os BSD 4.4
.Sh NAME
.Nm echo
.Nd produce message in a shell script
.Sh SYNOPSIS
.Nm
.Op Fl n | Fl e
.Ar args...
.Sh DESCRIPTION
.Nm
prints its arguments on the standard output, separated by spaces.
Unless the
.Fl n
option is present, a newline is output following the arguments.
The
.Fl e
option causes
.Nm
to treat the escape sequences specially, as described in the following
paragraph.
The
.Fl e
option is the default, and is provided solely for compatibility with
other systems.
Only one of the options
.Fl n
and
.Fl e
may be given.
.Pp
If any of the following sequences of characters is encountered during
output, the sequence is not output. Instead, the specified action is
performed:
.Bl -tag -width indent
.It Li \eb
A backspace character is output.
.It Li \ec
Subsequent output is suppressed. This is normally used at the end of the
last argument to suppress the trailing newline that
.Nm
would otherwise output.
.It Li \ef
Output a form feed.
.It Li \en
Output a newline character.
.It Li \er
Output a carriage return.
.It Li \et
Output a (horizontal) tab character.
.It Li \ev
Output a vertical tab.
.It Li \e0 Ns Ar digits
Output the character whose value is given by zero to three digits.
If there are zero digits, a nul character is output.
.It Li \e\e
Output a backslash.
.El
.Sh HINTS
Remember that backslash is special to the shell and needs to be escaped.
To output a message to standard error, say
.Pp
.D1 echo message >&2
.Sh BUGS
The octal character escape mechanism
.Pq Li \e0 Ns Ar digits
differs from the
C language mechanism.
.Pp
There is no way to force
.Nm
to treat its arguments literally, rather than interpreting them as
options and escape sequences.

View File

@ -1,107 +0,0 @@
/* $NetBSD: echo.c,v 1.8 1996/11/02 18:26:06 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)echo.c 8.1 (Berkeley) 5/31/93
*/
/*
* Echo command.
*/
#define main echocmd
#include "bltin.h"
/* #define eflag 1 */
int
main(argc, argv) char **argv; {
register char **ap;
register char *p;
register char c;
int count;
int nflag = 0;
#ifndef eflag
int eflag = 0;
#endif
ap = argv;
if (argc)
ap++;
if ((p = *ap) != NULL) {
if (equal(p, "-n")) {
nflag++;
ap++;
} else if (equal(p, "-e")) {
#ifndef eflag
eflag++;
#endif
ap++;
}
}
while ((p = *ap++) != NULL) {
while ((c = *p++) != '\0') {
if (c == '\\' && eflag) {
switch (*p++) {
case 'b': c = '\b'; break;
case 'c': return 0; /* exit */
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\\': break; /* c = '\\' */
case '0':
c = 0;
count = 3;
while (--count >= 0 && (unsigned)(*p - '0') < 8)
c = (c << 3) + (*p++ - '0');
break;
default:
p--;
break;
}
}
putchar(c);
}
if (*ap)
putchar(' ');
}
if (! nflag)
putchar('\n');
return 0;
}

View File

@ -1,92 +0,0 @@
#!/bin/sh -
# $NetBSD: builtins.def,v 1.14 1997/03/14 01:42:18 christos Exp $
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)builtins.def 8.4 (Berkeley) 5/4/95
#
# This file lists all the builtin commands. The first column is the name
# of a C routine. The -j flag, if present, specifies that this command
# is to be excluded from systems without job control, and the -h flag,
# if present specifies that this command is to be excluded from systems
# based on the SMALL compile-time symbol. The rest of the line
# specifies the command name or names used to run the command. The entry
# for bltincmd, which is run when the user does not specify a command, must
# come first.
#
# NOTE: bltincmd must come first!
bltincmd command
#alloccmd alloc
bgcmd -j bg
breakcmd break continue
#catfcmd catf
cdcmd cd chdir
dotcmd .
echocmd echo
evalcmd eval
execcmd exec
exitcmd exit
expcmd exp let
exportcmd export readonly
#exprcmd expr test [
falsecmd false
histcmd -h fc
fgcmd -j fg
getoptscmd getopts
hashcmd hash
jobidcmd jobid
jobscmd jobs
#linecmd line
localcmd local
#nlechocmd nlecho
#printfcmd printf
pwdcmd pwd
readcmd read
returncmd return
setcmd set
setvarcmd setvar
shiftcmd shift
trapcmd trap
truecmd : true
typecmd type
umaskcmd umask
unaliascmd unalias
unsetcmd unset
waitcmd wait
#foocmd foo
aliascmd alias
ulimitcmd ulimit

View File

@ -1,383 +0,0 @@
/* $NetBSD: cd.c,v 1.23 1997/07/04 20:59:40 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: cd.c,v 1.23 1997/07/04 20:59:40 christos Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
/*
* The cd and pwd commands.
*/
#include "shell.h"
#include "var.h"
#include "nodes.h" /* for jobs.h */
#include "jobs.h"
#include "options.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "exec.h"
#include "redir.h"
#include "mystring.h"
#include "show.h"
#include "cd.h"
STATIC int docd __P((char *, int));
STATIC char *getcomponent __P((void));
STATIC void updatepwd __P((char *));
char *curdir = NULL; /* current working directory */
char *prevdir; /* previous working directory */
STATIC char *cdcomppath;
int
cdcmd(argc, argv)
int argc;
char **argv;
{
char *dest;
char *path;
char *p;
struct stat statb;
int print = 0;
nextopt(nullstr);
if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME", 1)) == NULL)
error("HOME not set");
if (*dest == '\0')
dest = ".";
if (dest[0] == '-' && dest[1] == '\0') {
dest = prevdir ? prevdir : curdir;
print = 1;
if (dest)
print = 1;
else
dest = ".";
}
if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL)
path = nullstr;
while ((p = padvance(&path, dest)) != NULL) {
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
if (!print) {
/*
* XXX - rethink
*/
if (p[0] == '.' && p[1] == '/')
p += 2;
print = strcmp(p, dest);
}
if (docd(p, print) >= 0)
return 0;
}
}
error("can't cd to %s", dest);
/*NOTREACHED*/
return 0;
}
/*
* Actually do the chdir. In an interactive shell, print the
* directory name if "print" is nonzero.
*/
STATIC int
docd(dest, print)
char *dest;
int print;
{
char *p;
char *q;
char *component;
struct stat statb;
int first;
int badstat;
TRACE(("docd(\"%s\", %d) called\n", dest, print));
/*
* Check each component of the path. If we find a symlink or
* something we can't stat, clear curdir to force a getcwd()
* next time we get the value of the current directory.
*/
badstat = 0;
cdcomppath = stalloc(strlen(dest) + 1);
scopy(dest, cdcomppath);
STARTSTACKSTR(p);
if (*dest == '/') {
STPUTC('/', p);
cdcomppath++;
}
first = 1;
while ((q = getcomponent()) != NULL) {
if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
continue;
if (! first)
STPUTC('/', p);
first = 0;
component = q;
while (*q)
STPUTC(*q++, p);
if (equal(component, ".."))
continue;
STACKSTRNUL(p);
if ((lstat(stackblock(), &statb) < 0)
|| (S_ISLNK(statb.st_mode))) {
/* print = 1; */
badstat = 1;
break;
}
}
INTOFF;
if (chdir(dest) < 0) {
INTON;
return -1;
}
updatepwd(badstat ? NULL : dest);
INTON;
if (print && iflag && curdir)
out1fmt("%s\n", curdir);
return 0;
}
/*
* Get the next component of the path name pointed to by cdcomppath.
* This routine overwrites the string pointed to by cdcomppath.
*/
STATIC char *
getcomponent() {
char *p;
char *start;
if ((p = cdcomppath) == NULL)
return NULL;
start = cdcomppath;
while (*p != '/' && *p != '\0')
p++;
if (*p == '\0') {
cdcomppath = NULL;
} else {
*p++ = '\0';
cdcomppath = p;
}
return start;
}
/*
* Update curdir (the name of the current directory) in response to a
* cd command. We also call hashcd to let the routines in exec.c know
* that the current directory has changed.
*/
STATIC void
updatepwd(dir)
char *dir;
{
char *new;
char *p;
hashcd(); /* update command hash table */
/*
* If our argument is NULL, we don't know the current directory
* any more because we traversed a symbolic link or something
* we couldn't stat().
*/
if (dir == NULL) {
if (prevdir)
ckfree(prevdir);
INTOFF;
prevdir = curdir;
curdir = NULL;
getpwd();
INTON;
return;
}
cdcomppath = stalloc(strlen(dir) + 1);
scopy(dir, cdcomppath);
STARTSTACKSTR(new);
if (*dir != '/') {
if (curdir == NULL)
return;
p = curdir;
while (*p)
STPUTC(*p++, new);
if (p[-1] == '/')
STUNPUTC(new);
}
while ((p = getcomponent()) != NULL) {
if (equal(p, "..")) {
while (new > stackblock() && (STUNPUTC(new), *new) != '/');
} else if (*p != '\0' && ! equal(p, ".")) {
STPUTC('/', new);
while (*p)
STPUTC(*p++, new);
}
}
if (new == stackblock())
STPUTC('/', new);
STACKSTRNUL(new);
INTOFF;
if (prevdir)
ckfree(prevdir);
prevdir = curdir;
curdir = savestr(stackblock());
setvar("PWD", curdir, VEXPORT|VTEXTFIXED);
INTON;
}
int
pwdcmd(argc, argv)
int argc;
char **argv;
{
getpwd();
out1str(curdir);
out1c('\n');
return 0;
}
#define MAXPWD 256
/*
* Find out what the current directory is. If we already know the current
* directory, this routine returns immediately.
*/
void
getpwd()
{
char buf[MAXPWD];
if (curdir)
return;
/*
* Things are a bit complicated here; we could have just used
* getcwd, but traditionally getcwd is implemented using popen
* to /bin/pwd. This creates a problem for us, since we cannot
* keep track of the job if it is being ran behind our backs.
* So we re-implement getcwd(), and we suppress interrupts
* throughout the process. This is not completely safe, since
* the user can still break out of it by killing the pwd program.
* We still try to use getcwd for systems that we know have a
* c implementation of getcwd, that does not open a pipe to
* /bin/pwd.
*/
#if defined(__NetBSD__) || defined(__SVR4)
if (getcwd(buf, sizeof(buf)) == NULL) {
char *pwd = getenv("PWD");
struct stat stdot, stpwd;
if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
curdir = savestr(pwd);
return;
}
error("getcwd() failed: %s", strerror(errno));
}
curdir = savestr(buf);
#else
{
char *p;
int i;
int status;
struct job *jp;
int pip[2];
INTOFF;
if (pipe(pip) < 0)
error("Pipe call failed");
jp = makejob((union node *)NULL, 1);
if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) {
(void) close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
close(pip[1]);
}
(void) execl("/bin/pwd", "pwd", (char *)0);
error("Cannot exec /bin/pwd");
}
(void) close(pip[1]);
pip[1] = -1;
p = buf;
while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0
|| (i == -1 && errno == EINTR)) {
if (i > 0)
p += i;
}
(void) close(pip[0]);
pip[0] = -1;
status = waitforjob(jp);
if (status != 0)
error((char *)0);
if (i < 0 || p == buf || p[-1] != '\n')
error("pwd command failed");
p[-1] = '\0';
}
curdir = savestr(buf);
INTON;
#endif
}

View File

@ -1,39 +0,0 @@
/* $NetBSD: cd.h,v 1.2 1997/07/04 21:01:52 christos Exp $ */
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
void getpwd __P((void));
int cdcmd __P((int, char **));
int pwdcmd __P((int, char **));

View File

@ -1,291 +0,0 @@
/* $NetBSD: error.c,v 1.17 1997/07/04 21:01:54 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: error.c,v 1.17 1997/07/04 21:01:54 christos Exp $");
#endif
#endif /* not lint */
/*
* Errors and exceptions.
*/
#include "shell.h"
#include "main.h"
#include "options.h"
#include "output.h"
#include "error.h"
#include "show.h"
#include <signal.h>
#include <unistd.h>
#include <errno.h>
/*
* Code to handle exceptions in C.
*/
struct jmploc *handler;
int exception;
volatile int suppressint;
volatile int intpending;
char *commandname;
static void exverror __P((int, char *, va_list)) __attribute__((__noreturn__));
/*
* Called to raise an exception. Since C doesn't include exceptions, we
* just do a longjmp to the exception handler. The type of exception is
* stored in the global variable "exception".
*/
void
exraise(e)
int e;
{
if (handler == NULL)
abort();
exception = e;
longjmp(handler->loc, 1);
}
/*
* Called from trap.c when a SIGINT is received. (If the user specifies
* that SIGINT is to be trapped or ignored using the trap builtin, then
* this routine is not called.) Suppressint is nonzero when interrupts
* are held using the INTOFF macro. The call to _exit is necessary because
* there is a short period after a fork before the signal handlers are
* set to the appropriate value for the child. (The test for iflag is
* just defensive programming.)
*/
void
onint() {
sigset_t sigset;
if (suppressint) {
intpending++;
return;
}
intpending = 0;
sigemptyset(&sigset);
sigprocmask(SIG_SETMASK, &sigset, NULL);
if (rootshell && iflag)
exraise(EXINT);
else
_exit(128 + SIGINT);
}
/*
* Exverror is called to raise the error exception. If the first argument
* is not NULL then error prints an error message using printf style
* formatting. It then raises the error exception.
*/
static void
exverror(cond, msg, ap)
int cond;
char *msg;
va_list ap;
{
CLEAR_PENDING_INT;
INTOFF;
#ifdef DEBUG
if (msg)
TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
else
TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
#endif
if (msg) {
if (commandname)
outfmt(&errout, "%s: ", commandname);
doformat(&errout, msg, ap);
out2c('\n');
}
flushall();
exraise(cond);
}
#ifdef __STDC__
void
error(char *msg, ...)
#else
void
error(va_alist)
va_dcl
#endif
{
#ifndef __STDC__
char *msg;
#endif
va_list ap;
#ifdef __STDC__
va_start(ap, msg);
#else
va_start(ap);
msg = va_arg(ap, char *);
#endif
exverror(EXERROR, msg, ap);
va_end(ap);
}
#ifdef __STDC__
void
exerror(int cond, char *msg, ...)
#else
void
exerror(va_alist)
va_dcl
#endif
{
#ifndef __STDC__
int cond;
char *msg;
#endif
va_list ap;
#ifdef __STDC__
va_start(ap, msg);
#else
va_start(ap);
cond = va_arg(ap, int);
msg = va_arg(ap, char *);
#endif
exverror(cond, msg, ap);
va_end(ap);
}
/*
* Table of error messages.
*/
struct errname {
short errcode; /* error number */
short action; /* operation which encountered the error */
char *msg; /* text describing the error */
};
#define ALL (E_OPEN|E_CREAT|E_EXEC)
STATIC const struct errname errormsg[] = {
{ EINTR, ALL, "interrupted" },
{ EACCES, ALL, "permission denied" },
{ EIO, ALL, "I/O error" },
{ ENOENT, E_OPEN, "no such file" },
{ ENOENT, E_CREAT,"directory nonexistent" },
{ ENOENT, E_EXEC, "not found" },
{ ENOTDIR, E_OPEN, "no such file" },
{ ENOTDIR, E_CREAT,"directory nonexistent" },
{ ENOTDIR, E_EXEC, "not found" },
{ EISDIR, ALL, "is a directory" },
#ifdef notdef
{ EMFILE, ALL, "too many open files" },
#endif
{ ENFILE, ALL, "file table overflow" },
{ ENOSPC, ALL, "file system full" },
#ifdef EDQUOT
{ EDQUOT, ALL, "disk quota exceeded" },
#endif
#ifdef ENOSR
{ ENOSR, ALL, "no streams resources" },
#endif
{ ENXIO, ALL, "no such device or address" },
{ EROFS, ALL, "read-only file system" },
{ ETXTBSY, ALL, "text busy" },
#ifdef SYSV
{ EAGAIN, E_EXEC, "not enough memory" },
#endif
{ ENOMEM, ALL, "not enough memory" },
#ifdef ENOLINK
{ ENOLINK, ALL, "remote access failed" },
#endif
#ifdef EMULTIHOP
{ EMULTIHOP, ALL, "remote access failed" },
#endif
#ifdef ECOMM
{ ECOMM, ALL, "remote access failed" },
#endif
#ifdef ESTALE
{ ESTALE, ALL, "remote access failed" },
#endif
#ifdef ETIMEDOUT
{ ETIMEDOUT, ALL, "remote access failed" },
#endif
#ifdef ELOOP
{ ELOOP, ALL, "symbolic link loop" },
#endif
{ E2BIG, E_EXEC, "argument list too long" },
#ifdef ELIBACC
{ ELIBACC, E_EXEC, "shared library missing" },
#endif
{ 0, 0, NULL },
};
/*
* Return a string describing an error. The returned string may be a
* pointer to a static buffer that will be overwritten on the next call.
* Action describes the operation that got the error.
*/
char *
errmsg(e, action)
int e;
int action;
{
struct errname const *ep;
static char buf[12];
for (ep = errormsg ; ep->errcode ; ep++) {
if (ep->errcode == e && (ep->action & action) != 0)
return ep->msg;
}
fmtstr(buf, sizeof buf, "error %d", e);
return buf;
}

View File

@ -1,108 +0,0 @@
/* $NetBSD: error.h,v 1.10 1997/07/04 21:01:55 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)error.h 8.2 (Berkeley) 5/4/95
*/
/*
* Types of operations (passed to the errmsg routine).
*/
#define E_OPEN 01 /* opening a file */
#define E_CREAT 02 /* creating a file */
#define E_EXEC 04 /* executing a program */
/*
* We enclose jmp_buf in a structure so that we can declare pointers to
* jump locations. The global variable handler contains the location to
* jump to when an exception occurs, and the global variable exception
* contains a code identifying the exeception. To implement nested
* exception handlers, the user should save the value of handler on entry
* to an inner scope, set handler to point to a jmploc structure for the
* inner scope, and restore handler on exit from the scope.
*/
#include <setjmp.h>
struct jmploc {
jmp_buf loc;
};
extern struct jmploc *handler;
extern int exception;
/* exceptions */
#define EXINT 0 /* SIGINT received */
#define EXERROR 1 /* a generic error */
#define EXSHELLPROC 2 /* execute a shell procedure */
#define EXEXEC 3 /* command execution failed */
/*
* These macros allow the user to suspend the handling of interrupt signals
* over a period of time. This is similar to SIGHOLD to or sigblock, but
* much more efficient and portable. (But hacking the kernel is so much
* more fun than worrying about efficiency and portability. :-))
*/
extern volatile int suppressint;
extern volatile int intpending;
extern char *commandname; /* name of command--printed on error */
#define INTOFF suppressint++
#define INTON { if (--suppressint == 0 && intpending) onint(); }
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
#define CLEAR_PENDING_INT intpending = 0
#define int_pending() intpending
void exraise __P((int)) __attribute__((__noreturn__));
void onint __P((void));
void error __P((char *, ...)) __attribute__((__noreturn__));
void exerror __P((int, char *, ...));
char *errmsg __P((int, int));
/*
* BSD setjmp saves the signal mask, which violates ANSI C and takes time,
* so we use _setjmp instead.
*/
#ifdef BSD
#define setjmp(jmploc) _setjmp(jmploc)
#define longjmp(jmploc, val) _longjmp(jmploc, val)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
/* $NetBSD: eval.h,v 1.9 1995/09/11 17:05:43 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)eval.h 8.2 (Berkeley) 5/4/95
*/
extern char *commandname; /* currently executing command */
extern int exitstatus; /* exit status of last command */
extern struct strlist *cmdenviron; /* environment for builtin command */
struct backcmd { /* result of evalbackcmd */
int fd; /* file descriptor to read from */
char *buf; /* buffer */
int nleft; /* number of chars in buffer */
struct job *jp; /* job structure for command */
};
int evalcmd __P((int, char **));
void evalstring __P((char *));
union node; /* BLETCH for ansi C */
void evaltree __P((union node *, int));
void evalbackcmd __P((union node *, struct backcmd *));
int bltincmd __P((int, char **));
int breakcmd __P((int, char **));
int returncmd __P((int, char **));
int falsecmd __P((int, char **));
int truecmd __P((int, char **));
int execcmd __P((int, char **));
/* in_function returns nonzero if we are currently evaluating a function */
#define in_function() funcnest
extern int funcnest;
extern int evalskip;
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
#define SKIPFUNC 3
#define SKIPFILE 4

View File

@ -1,921 +0,0 @@
/* $NetBSD: exec.c,v 1.23 1997/07/04 21:01:59 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95";
#else
__RCSID("$NetBSD: exec.c,v 1.23 1997/07/04 21:01:59 christos Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
/*
* When commands are first encountered, they are entered in a hash table.
* This ensures that a full path search will not have to be done for them
* on each invocation.
*
* We should investigate converting to a linear search, even though that
* would make the command name "hash" a misnomer.
*/
#include "shell.h"
#include "main.h"
#include "nodes.h"
#include "parser.h"
#include "redir.h"
#include "eval.h"
#include "exec.h"
#include "builtins.h"
#include "var.h"
#include "options.h"
#include "input.h"
#include "output.h"
#include "syntax.h"
#include "memalloc.h"
#include "error.h"
#include "init.h"
#include "mystring.h"
#include "show.h"
#include "jobs.h"
#include "alias.h"
#define CMDTABLESIZE 31 /* should be prime */
#define ARB 1 /* actual size determined at run time */
struct tblentry {
struct tblentry *next; /* next entry in hash chain */
union param param; /* definition of builtin function */
short cmdtype; /* index identifying command */
char rehash; /* if set, cd done since entry created */
char cmdname[ARB]; /* name of command */
};
STATIC struct tblentry *cmdtable[CMDTABLESIZE];
STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */
int exerrno = 0; /* Last exec error */
STATIC void tryexec __P((char *, char **, char **));
STATIC void execinterp __P((char **, char **));
STATIC void printentry __P((struct tblentry *, int));
STATIC void clearcmdentry __P((int));
STATIC struct tblentry *cmdlookup __P((char *, int));
STATIC void delete_cmd_entry __P((void));
/*
* Exec a program. Never returns. If you change this routine, you may
* have to change the find_command routine as well.
*/
void
shellexec(argv, envp, path, index)
char **argv, **envp;
char *path;
int index;
{
char *cmdname;
int e;
if (strchr(argv[0], '/') != NULL) {
tryexec(argv[0], argv, envp);
e = errno;
} else {
e = ENOENT;
while ((cmdname = padvance(&path, argv[0])) != NULL) {
if (--index < 0 && pathopt == NULL) {
tryexec(cmdname, argv, envp);
if (errno != ENOENT && errno != ENOTDIR)
e = errno;
}
stunalloc(cmdname);
}
}
/* Map to POSIX errors */
switch (e) {
case EACCES:
exerrno = 126;
break;
case ENOENT:
exerrno = 127;
break;
default:
exerrno = 2;
break;
}
exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC));
}
STATIC void
tryexec(cmd, argv, envp)
char *cmd;
char **argv;
char **envp;
{
int e;
#ifndef BSD
char *p;
#endif
#ifdef SYSV
do {
execve(cmd, argv, envp);
} while (errno == EINTR);
#else
execve(cmd, argv, envp);
#endif
e = errno;
if (e == ENOEXEC) {
initshellproc();
setinputfile(cmd, 0);
commandname = arg0 = savestr(argv[0]);
#ifndef BSD
pgetc(); pungetc(); /* fill up input buffer */
p = parsenextc;
if (parsenleft > 2 && p[0] == '#' && p[1] == '!') {
argv[0] = cmd;
execinterp(argv, envp);
}
#endif
setparam(argv + 1);
exraise(EXSHELLPROC);
/*NOTREACHED*/
}
errno = e;
}
#ifndef BSD
/*
* Execute an interpreter introduced by "#!", for systems where this
* feature has not been built into the kernel. If the interpreter is
* the shell, return (effectively ignoring the "#!"). If the execution
* of the interpreter fails, exit.
*
* This code peeks inside the input buffer in order to avoid actually
* reading any input. It would benefit from a rewrite.
*/
#define NEWARGS 5
STATIC void
execinterp(argv, envp)
char **argv, **envp;
{
int n;
char *inp;
char *outp;
char c;
char *p;
char **ap;
char *newargs[NEWARGS];
int i;
char **ap2;
char **new;
n = parsenleft - 2;
inp = parsenextc + 2;
ap = newargs;
for (;;) {
while (--n >= 0 && (*inp == ' ' || *inp == '\t'))
inp++;
if (n < 0)
goto bad;
if ((c = *inp++) == '\n')
break;
if (ap == &newargs[NEWARGS])
bad: error("Bad #! line");
STARTSTACKSTR(outp);
do {
STPUTC(c, outp);
} while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n');
STPUTC('\0', outp);
n++, inp--;
*ap++ = grabstackstr(outp);
}
if (ap == newargs + 1) { /* if no args, maybe no exec is needed */
p = newargs[0];
for (;;) {
if (equal(p, "sh") || equal(p, "ash")) {
return;
}
while (*p != '/') {
if (*p == '\0')
goto break2;
p++;
}
p++;
}
break2:;
}
i = (char *)ap - (char *)newargs; /* size in bytes */
if (i == 0)
error("Bad #! line");
for (ap2 = argv ; *ap2++ != NULL ; );
new = ckmalloc(i + ((char *)ap2 - (char *)argv));
ap = newargs, ap2 = new;
while ((i -= sizeof (char **)) >= 0)
*ap2++ = *ap++;
ap = argv;
while (*ap2++ = *ap++);
shellexec(new, envp, pathval(), 0);
}
#endif
/*
* Do a path search. The variable path (passed by reference) should be
* set to the start of the path before the first call; padvance will update
* this value as it proceeds. Successive calls to padvance will return
* the possible path expansions in sequence. If an option (indicated by
* a percent sign) appears in the path entry then the global variable
* pathopt will be set to point to it; otherwise pathopt will be set to
* NULL.
*/
char *pathopt;
char *
padvance(path, name)
char **path;
char *name;
{
char *p, *q;
char *start;
int len;
if (*path == NULL)
return NULL;
start = *path;
for (p = start ; *p && *p != ':' && *p != '%' ; p++);
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */
while (stackblocksize() < len)
growstackblock();
q = stackblock();
if (p != start) {
memcpy(q, start, p - start);
q += p - start;
*q++ = '/';
}
strcpy(q, name);
pathopt = NULL;
if (*p == '%') {
pathopt = ++p;
while (*p && *p != ':') p++;
}
if (*p == ':')
*path = p + 1;
else
*path = NULL;
return stalloc(len);
}
/*** Command hashing code ***/
int
hashcmd(argc, argv)
int argc;
char **argv;
{
struct tblentry **pp;
struct tblentry *cmdp;
int c;
int verbose;
struct cmdentry entry;
char *name;
verbose = 0;
while ((c = nextopt("rv")) != '\0') {
if (c == 'r') {
clearcmdentry(0);
} else if (c == 'v') {
verbose++;
}
}
if (*argptr == NULL) {
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
printentry(cmdp, verbose);
}
}
return 0;
}
while ((name = *argptr) != NULL) {
if ((cmdp = cmdlookup(name, 0)) != NULL
&& (cmdp->cmdtype == CMDNORMAL
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
delete_cmd_entry();
find_command(name, &entry, 1, pathval());
if (verbose) {
if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */
cmdp = cmdlookup(name, 0);
printentry(cmdp, verbose);
}
flushall();
}
argptr++;
}
return 0;
}
STATIC void
printentry(cmdp, verbose)
struct tblentry *cmdp;
int verbose;
{
int index;
char *path;
char *name;
if (cmdp->cmdtype == CMDNORMAL) {
index = cmdp->param.index;
path = pathval();
do {
name = padvance(&path, cmdp->cmdname);
stunalloc(name);
} while (--index >= 0);
out1str(name);
} else if (cmdp->cmdtype == CMDBUILTIN) {
out1fmt("builtin %s", cmdp->cmdname);
} else if (cmdp->cmdtype == CMDFUNCTION) {
out1fmt("function %s", cmdp->cmdname);
if (verbose) {
INTOFF;
name = commandtext(cmdp->param.func);
out1c(' ');
out1str(name);
ckfree(name);
INTON;
}
#ifdef DEBUG
} else {
error("internal error: cmdtype %d", cmdp->cmdtype);
#endif
}
if (cmdp->rehash)
out1c('*');
out1c('\n');
}
/*
* Resolve a command name. If you change this routine, you may have to
* change the shellexec routine as well.
*/
void
find_command(name, entry, printerr, path)
char *name;
struct cmdentry *entry;
int printerr;
char *path;
{
struct tblentry *cmdp;
int index;
int prev;
char *fullname;
struct stat statb;
int e;
int i;
/* If name contains a slash, don't use the hash table */
if (strchr(name, '/') != NULL) {
entry->cmdtype = CMDNORMAL;
entry->u.index = 0;
return;
}
/* If name is in the table, and not invalidated by cd, we're done */
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0)
goto success;
/* If %builtin not in path, check for builtin next */
if (builtinloc < 0 && (i = find_builtin(name)) >= 0) {
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
INTON;
goto success;
}
/* We have to search path. */
prev = -1; /* where to start */
if (cmdp) { /* doing a rehash */
if (cmdp->cmdtype == CMDBUILTIN)
prev = builtinloc;
else
prev = cmdp->param.index;
}
e = ENOENT;
index = -1;
loop:
while ((fullname = padvance(&path, name)) != NULL) {
stunalloc(fullname);
index++;
if (pathopt) {
if (prefix("builtin", pathopt)) {
if ((i = find_builtin(name)) < 0)
goto loop;
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDBUILTIN;
cmdp->param.index = i;
INTON;
goto success;
} else if (prefix("func", pathopt)) {
/* handled below */
} else {
goto loop; /* ignore unimplemented options */
}
}
/* if rehash, don't redo absolute path names */
if (fullname[0] == '/' && index <= prev) {
if (index < prev)
goto loop;
TRACE(("searchexec \"%s\": no change\n", name));
goto success;
}
while (stat(fullname, &statb) < 0) {
#ifdef SYSV
if (errno == EINTR)
continue;
#endif
if (errno != ENOENT && errno != ENOTDIR)
e = errno;
goto loop;
}
e = EACCES; /* if we fail, this will be the error */
if (!S_ISREG(statb.st_mode))
goto loop;
if (pathopt) { /* this is a %func directory */
stalloc(strlen(fullname) + 1);
readcmdfile(fullname);
if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION)
error("%s not defined in %s", name, fullname);
stunalloc(fullname);
goto success;
}
#ifdef notdef
if (statb.st_uid == geteuid()) {
if ((statb.st_mode & 0100) == 0)
goto loop;
} else if (statb.st_gid == getegid()) {
if ((statb.st_mode & 010) == 0)
goto loop;
} else {
if ((statb.st_mode & 01) == 0)
goto loop;
}
#endif
TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
INTOFF;
cmdp = cmdlookup(name, 1);
cmdp->cmdtype = CMDNORMAL;
cmdp->param.index = index;
INTON;
goto success;
}
/* We failed. If there was an entry for this command, delete it */
if (cmdp)
delete_cmd_entry();
if (printerr)
outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
entry->cmdtype = CMDUNKNOWN;
return;
success:
cmdp->rehash = 0;
entry->cmdtype = cmdp->cmdtype;
entry->u = cmdp->param;
}
/*
* Search the table of builtin commands.
*/
int
find_builtin(name)
char *name;
{
const struct builtincmd *bp;
for (bp = builtincmd ; bp->name ; bp++) {
if (*bp->name == *name && equal(bp->name, name))
return bp->code;
}
return -1;
}
/*
* Called when a cd is done. Marks all commands so the next time they
* are executed they will be rehashed.
*/
void
hashcd() {
struct tblentry **pp;
struct tblentry *cmdp;
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (cmdp->cmdtype == CMDNORMAL
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
cmdp->rehash = 1;
}
}
}
/*
* Called before PATH is changed. The argument is the new value of PATH;
* pathval() still returns the old value at this point. Called with
* interrupts off.
*/
void
changepath(newval)
const char *newval;
{
const char *old, *new;
int index;
int firstchange;
int bltin;
old = pathval();
new = newval;
firstchange = 9999; /* assume no change */
index = 0;
bltin = -1;
for (;;) {
if (*old != *new) {
firstchange = index;
if ((*old == '\0' && *new == ':')
|| (*old == ':' && *new == '\0'))
firstchange++;
old = new; /* ignore subsequent differences */
}
if (*new == '\0')
break;
if (*new == '%' && bltin < 0 && prefix("builtin", new + 1))
bltin = index;
if (*new == ':') {
index++;
}
new++, old++;
}
if (builtinloc < 0 && bltin >= 0)
builtinloc = bltin; /* zap builtins */
if (builtinloc >= 0 && bltin < 0)
firstchange = 0;
clearcmdentry(firstchange);
builtinloc = bltin;
}
/*
* Clear out command entries. The argument specifies the first entry in
* PATH which has changed.
*/
STATIC void
clearcmdentry(firstchange)
int firstchange;
{
struct tblentry **tblp;
struct tblentry **pp;
struct tblentry *cmdp;
INTOFF;
for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
pp = tblp;
while ((cmdp = *pp) != NULL) {
if ((cmdp->cmdtype == CMDNORMAL &&
cmdp->param.index >= firstchange)
|| (cmdp->cmdtype == CMDBUILTIN &&
builtinloc >= firstchange)) {
*pp = cmdp->next;
ckfree(cmdp);
} else {
pp = &cmdp->next;
}
}
}
INTON;
}
/*
* Delete all functions.
*/
#ifdef mkinit
MKINIT void deletefuncs __P((void));
SHELLPROC {
deletefuncs();
}
#endif
void
deletefuncs() {
struct tblentry **tblp;
struct tblentry **pp;
struct tblentry *cmdp;
INTOFF;
for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
pp = tblp;
while ((cmdp = *pp) != NULL) {
if (cmdp->cmdtype == CMDFUNCTION) {
*pp = cmdp->next;
freefunc(cmdp->param.func);
ckfree(cmdp);
} else {
pp = &cmdp->next;
}
}
}
INTON;
}
/*
* Locate a command in the command hash table. If "add" is nonzero,
* add the command to the table if it is not already present. The
* variable "lastcmdentry" is set to point to the address of the link
* pointing to the entry, so that delete_cmd_entry can delete the
* entry.
*/
struct tblentry **lastcmdentry;
STATIC struct tblentry *
cmdlookup(name, add)
char *name;
int add;
{
int hashval;
char *p;
struct tblentry *cmdp;
struct tblentry **pp;
p = name;
hashval = *p << 4;
while (*p)
hashval += *p++;
hashval &= 0x7FFF;
pp = &cmdtable[hashval % CMDTABLESIZE];
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (equal(cmdp->cmdname, name))
break;
pp = &cmdp->next;
}
if (add && cmdp == NULL) {
INTOFF;
cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
+ strlen(name) + 1);
cmdp->next = NULL;
cmdp->cmdtype = CMDUNKNOWN;
cmdp->rehash = 0;
strcpy(cmdp->cmdname, name);
INTON;
}
lastcmdentry = pp;
return cmdp;
}
/*
* Delete the command entry returned on the last lookup.
*/
STATIC void
delete_cmd_entry() {
struct tblentry *cmdp;
INTOFF;
cmdp = *lastcmdentry;
*lastcmdentry = cmdp->next;
ckfree(cmdp);
INTON;
}
#ifdef notdef
void
getcmdentry(name, entry)
char *name;
struct cmdentry *entry;
{
struct tblentry *cmdp = cmdlookup(name, 0);
if (cmdp) {
entry->u = cmdp->param;
entry->cmdtype = cmdp->cmdtype;
} else {
entry->cmdtype = CMDUNKNOWN;
entry->u.index = 0;
}
}
#endif
/*
* Add a new command entry, replacing any existing command entry for
* the same name.
*/
void
addcmdentry(name, entry)
char *name;
struct cmdentry *entry;
{
struct tblentry *cmdp;
INTOFF;
cmdp = cmdlookup(name, 1);
if (cmdp->cmdtype == CMDFUNCTION) {
freefunc(cmdp->param.func);
}
cmdp->cmdtype = entry->cmdtype;
cmdp->param = entry->u;
INTON;
}
/*
* Define a shell function.
*/
void
defun(name, func)
char *name;
union node *func;
{
struct cmdentry entry;
INTOFF;
entry.cmdtype = CMDFUNCTION;
entry.u.func = copyfunc(func);
addcmdentry(name, &entry);
INTON;
}
/*
* Delete a function if it exists.
*/
int
unsetfunc(name)
char *name;
{
struct tblentry *cmdp;
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
freefunc(cmdp->param.func);
delete_cmd_entry();
return (0);
}
return (1);
}
/*
* Locate and print what a word is...
*/
int
typecmd(argc, argv)
int argc;
char **argv;
{
struct cmdentry entry;
struct tblentry *cmdp;
char **pp;
struct alias *ap;
int i;
int error = 0;
extern char *const parsekwd[];
for (i = 1; i < argc; i++) {
out1str(argv[i]);
/* First look at the keywords */
for (pp = (char **)parsekwd; *pp; pp++)
if (**pp == *argv[i] && equal(*pp, argv[i]))
break;
if (*pp) {
out1str(" is a shell keyword\n");
continue;
}
/* Then look at the aliases */
if ((ap = lookupalias(argv[i], 1)) != NULL) {
out1fmt(" is an alias for %s\n", ap->val);
continue;
}
/* Then check if it is a tracked alias */
if ((cmdp = cmdlookup(argv[i], 0)) != NULL) {
entry.cmdtype = cmdp->cmdtype;
entry.u = cmdp->param;
}
else {
/* Finally use brute force */
find_command(argv[i], &entry, 0, pathval());
}
switch (entry.cmdtype) {
case CMDNORMAL: {
int j = entry.u.index;
char *path = pathval(), *name;
do {
name = padvance(&path, argv[i]);
stunalloc(name);
} while (--j >= 0);
out1fmt(" is%s %s\n",
cmdp ? " a tracked alias for" : "", name);
break;
}
case CMDFUNCTION:
out1str(" is a shell function\n");
break;
case CMDBUILTIN:
out1str(" is a shell builtin\n");
break;
default:
out1str(" not found\n");
error |= 127;
break;
}
}
return error;
}

View File

@ -1,72 +0,0 @@
/* $NetBSD: exec.h,v 1.12 1997/02/06 23:24:53 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)exec.h 8.3 (Berkeley) 6/8/95
*/
/* values of cmdtype */
#define CMDUNKNOWN -1 /* no entry in table for command */
#define CMDNORMAL 0 /* command is an executable program */
#define CMDBUILTIN 1 /* command is a shell builtin */
#define CMDFUNCTION 2 /* command is a shell function */
struct cmdentry {
int cmdtype;
union param {
int index;
union node *func;
} u;
};
extern char *pathopt; /* set by padvance */
extern int exerrno; /* last exec error */
void shellexec __P((char **, char **, char *, int));
char *padvance __P((char **, char *));
int hashcmd __P((int, char **));
void find_command __P((char *, struct cmdentry *, int, char *));
int find_builtin __P((char *));
void hashcd __P((void));
void changepath __P((const char *));
void deletefuncs __P((void));
void getcmdentry __P((char *, struct cmdentry *));
void addcmdentry __P((char *, struct cmdentry *));
void defun __P((char *, union node *));
int unsetfunc __P((char *));
int typecmd __P((int, char **));

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +0,0 @@
/* $NetBSD: expand.h,v 1.8 1995/05/11 21:29:08 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)expand.h 8.2 (Berkeley) 5/4/95
*/
struct strlist {
struct strlist *next;
char *text;
};
struct arglist {
struct strlist *list;
struct strlist **lastp;
};
/*
* expandarg() flags
*/
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
union node;
void expandhere __P((union node *, int));
void expandarg __P((union node *, struct arglist *, int));
void expari __P((int));
int patmatch __P((char *, char *));
void rmescapes __P((char *));
int casematch __P((union node *, char *));

View File

@ -1,50 +0,0 @@
# $NetBSD: cmv,v 1.7 1995/05/11 21:31:05 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)cmv 8.2 (Berkeley) 5/4/95
# Conditional move--don't replace an existing file.
cmv() {
if test $# != 2
then echo "cmv: arg count"
return 2
fi
if test -f "$2" -o -w "$2"
then echo "$2 exists"
return 2
fi
/bin/mv "$1" "$2"
}

View File

@ -1,74 +0,0 @@
# $NetBSD: dirs,v 1.7 1995/05/11 21:31:08 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)dirs 8.2 (Berkeley) 5/4/95
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW
pushd () {
SAVE=`pwd`
if [ "$1" = "" ]
then if [ "$DSTACK" = "" ]
then echo "pushd: directory stack empty."
return 1
fi
set $DSTACK
cd $1 || return
shift 1
DSTACK="$*"
else cd $1 > /dev/null || return
fi
DSTACK="$SAVE $DSTACK"
dirs
}
popd () {
if [ "$DSTACK" = "" ]
then echo "popd: directory stack empty."
return 1
fi
set $DSTACK
cd $1
shift
DSTACK=$*
dirs
}
dirs () {
echo "`pwd` $DSTACK"
return 0
}

View File

@ -1,50 +0,0 @@
# $NetBSD: kill,v 1.7 1995/05/11 21:31:10 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)kill 8.2 (Berkeley) 5/4/95
# Convert job names to process ids and then run /bin/kill.
kill() {
local args x
args=
for x in "$@"
do case $x in
%*) x=`jobid "$x"` ;;
esac
args="$args $x"
done
/bin/kill $args
}

View File

@ -1,39 +0,0 @@
# $NetBSD: login,v 1.7 1995/05/11 21:31:11 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)login 8.2 (Berkeley) 5/4/95
# replaces the login builtin in the BSD shell
login () exec login "$@"

View File

@ -1,38 +0,0 @@
# $NetBSD: newgrp,v 1.7 1995/05/11 21:31:12 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)newgrp 8.2 (Berkeley) 5/4/95
newgrp() exec newgrp "$@"

View File

@ -1,74 +0,0 @@
# $NetBSD: popd,v 1.7 1995/05/11 21:31:13 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)popd 8.2 (Berkeley) 5/4/95
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW
pushd () {
SAVE=`pwd`
if [ "$1" = "" ]
then if [ "$DSTACK" = "" ]
then echo "pushd: directory stack empty."
return 1
fi
set $DSTACK
cd $1 || return
shift 1
DSTACK="$*"
else cd $1 > /dev/null || return
fi
DSTACK="$SAVE $DSTACK"
dirs
}
popd () {
if [ "$DSTACK" = "" ]
then echo "popd: directory stack empty."
return 1
fi
set $DSTACK
cd $1
shift
DSTACK=$*
dirs
}
dirs () {
echo "`pwd` $DSTACK"
return 0
}

View File

@ -1,74 +0,0 @@
# $NetBSD: pushd,v 1.7 1995/05/11 21:31:15 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)pushd 8.2 (Berkeley) 5/4/95
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW
pushd () {
SAVE=`pwd`
if [ "$1" = "" ]
then if [ "$DSTACK" = "" ]
then echo "pushd: directory stack empty."
return 1
fi
set $DSTACK
cd $1 || return
shift 1
DSTACK="$*"
else cd $1 > /dev/null || return
fi
DSTACK="$SAVE $DSTACK"
dirs
}
popd () {
if [ "$DSTACK" = "" ]
then echo "popd: directory stack empty."
return 1
fi
set $DSTACK
cd $1
shift
DSTACK=$*
dirs
}
dirs () {
echo "`pwd` $DSTACK"
return 0
}

View File

@ -1,42 +0,0 @@
# $NetBSD: suspend,v 1.7 1995/05/11 21:31:17 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)suspend 8.2 (Berkeley) 5/4/95
suspend() {
local -
set +j
kill -TSTP 0
}

View File

@ -1,501 +0,0 @@
/* $NetBSD: histedit.c,v 1.14 1997/07/04 21:02:02 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: histedit.c,v 1.14 1997/07/04 21:02:02 christos Exp $");
#endif
#endif /* not lint */
#include <sys/param.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*
* Editline and history functions (and glue).
*/
#include "shell.h"
#include "parser.h"
#include "var.h"
#include "options.h"
#include "main.h"
#include "output.h"
#include "mystring.h"
#ifndef SMALL
#include "myhistedit.h"
#include "error.h"
#include "eval.h"
#include "memalloc.h"
#define MAXHISTLOOPS 4 /* max recursions through fc */
#define DEFEDITOR "ed" /* default editor *should* be $EDITOR */
History *hist; /* history cookie */
EditLine *el; /* editline cookie */
int displayhist;
static FILE *el_in, *el_out;
STATIC char *fc_replace __P((const char *, char *, char *));
/*
* Set history and editing status. Called whenever the status may
* have changed (figures out what to do).
*/
void
histedit()
{
#define editing (Eflag || Vflag)
if (iflag) {
if (!hist) {
/*
* turn history on
*/
INTOFF;
hist = history_init();
INTON;
if (hist != NULL)
sethistsize(histsizeval());
else
out2str("sh: can't initialize history\n");
}
if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
/*
* turn editing on
*/
INTOFF;
if (el_in == NULL)
el_in = fdopen(0, "r");
if (el_out == NULL)
el_out = fdopen(2, "w");
if (el_in == NULL || el_out == NULL)
goto bad;
el = el_init(arg0, el_in, el_out);
if (el != NULL) {
if (hist)
el_set(el, EL_HIST, history, hist);
el_set(el, EL_PROMPT, getprompt);
} else {
bad:
out2str("sh: can't initialize editing\n");
}
INTON;
} else if (!editing && el) {
INTOFF;
el_end(el);
el = NULL;
INTON;
}
if (el) {
if (Vflag)
el_set(el, EL_EDITOR, "vi");
else if (Eflag)
el_set(el, EL_EDITOR, "emacs");
}
} else {
INTOFF;
if (el) { /* no editing if not interactive */
el_end(el);
el = NULL;
}
if (hist) {
history_end(hist);
hist = NULL;
}
INTON;
}
}
void
sethistsize(hs)
const char *hs;
{
int histsize;
if (hist != NULL) {
if (hs == NULL || *hs == '\0' ||
(histsize = atoi(hs)) < 0)
histsize = 100;
history(hist, H_EVENT, histsize);
}
}
void
setterm(term)
const char *term;
{
if (el != NULL && term != NULL)
if (el_set(el, EL_TERMINAL, term) != 0) {
outfmt(out2, "sh: Can't set terminal type %s\n", term);
outfmt(out2, "sh: Using dumb terminal settings.\n");
}
}
/*
* This command is provided since POSIX decided to standardize
* the Korn shell fc command. Oh well...
*/
int
histcmd(argc, argv)
int argc;
char **argv;
{
extern char *optarg;
extern int optind, optopt, optreset;
int ch;
char *editor = NULL;
const HistEvent *he;
int lflg = 0, nflg = 0, rflg = 0, sflg = 0;
int i;
char *firststr, *laststr;
int first, last, direction;
char *pat = NULL, *repl; /* ksh "fc old=new" crap */
static int active = 0;
struct jmploc jmploc;
struct jmploc *volatile savehandler;
char editfile[MAXPATHLEN + 1];
FILE *efp;
#ifdef __GNUC__
/* Avoid longjmp clobbering */
(void) &editor;
(void) &lflg;
(void) &nflg;
(void) &rflg;
(void) &sflg;
(void) &firststr;
(void) &laststr;
(void) &pat;
(void) &repl;
(void) &efp;
(void) &argc;
(void) &argv;
#endif
if (hist == NULL)
error("history not active");
if (argc == 1)
error("missing history argument");
optreset = 1; optind = 1; /* initialize getopt */
while (not_fcnumber(argv[optind]) &&
(ch = getopt(argc, argv, ":e:lnrs")) != EOF)
switch ((char)ch) {
case 'e':
editor = optarg;
break;
case 'l':
lflg = 1;
break;
case 'n':
nflg = 1;
break;
case 'r':
rflg = 1;
break;
case 's':
sflg = 1;
break;
case ':':
error("option -%c expects argument", optopt);
case '?':
default:
error("unknown option: -%c", optopt);
}
argc -= optind, argv += optind;
/*
* If executing...
*/
if (lflg == 0 || editor || sflg) {
lflg = 0; /* ignore */
editfile[0] = '\0';
/*
* Catch interrupts to reset active counter and
* cleanup temp files.
*/
if (setjmp(jmploc.loc)) {
active = 0;
if (*editfile)
unlink(editfile);
handler = savehandler;
longjmp(handler->loc, 1);
}
savehandler = handler;
handler = &jmploc;
if (++active > MAXHISTLOOPS) {
active = 0;
displayhist = 0;
error("called recursively too many times");
}
/*
* Set editor.
*/
if (sflg == 0) {
if (editor == NULL &&
(editor = bltinlookup("FCEDIT", 1)) == NULL &&
(editor = bltinlookup("EDITOR", 1)) == NULL)
editor = DEFEDITOR;
if (editor[0] == '-' && editor[1] == '\0') {
sflg = 1; /* no edit */
editor = NULL;
}
}
}
/*
* If executing, parse [old=new] now
*/
if (lflg == 0 && argc > 0 &&
((repl = strchr(argv[0], '=')) != NULL)) {
pat = argv[0];
*repl++ = '\0';
argc--, argv++;
}
/*
* determine [first] and [last]
*/
switch (argc) {
case 0:
firststr = lflg ? "-16" : "-1";
laststr = "-1";
break;
case 1:
firststr = argv[0];
laststr = lflg ? "-1" : argv[0];
break;
case 2:
firststr = argv[0];
laststr = argv[1];
break;
default:
error("too many args");
}
/*
* Turn into event numbers.
*/
first = str_to_event(firststr, 0);
last = str_to_event(laststr, 1);
if (rflg) {
i = last;
last = first;
first = i;
}
/*
* XXX - this should not depend on the event numbers
* always increasing. Add sequence numbers or offset
* to the history element in next (diskbased) release.
*/
direction = first < last ? H_PREV : H_NEXT;
/*
* If editing, grab a temp file.
*/
if (editor) {
int fd;
INTOFF; /* easier */
sprintf(editfile, "%s/_shXXXXXX", _PATH_TMP);
if ((fd = mkstemp(editfile)) < 0)
error("can't create temporary file %s", editfile);
if ((efp = fdopen(fd, "w")) == NULL) {
close(fd);
error("can't allocate stdio buffer for temp");
}
}
/*
* Loop through selected history events. If listing or executing,
* do it now. Otherwise, put into temp file and call the editor
* after.
*
* The history interface needs rethinking, as the following
* convolutions will demonstrate.
*/
history(hist, H_FIRST);
he = history(hist, H_NEXT_EVENT, first);
for (;he != NULL; he = history(hist, direction)) {
if (lflg) {
if (!nflg)
out1fmt("%5d ", he->num);
out1str(he->str);
} else {
char *s = pat ?
fc_replace(he->str, pat, repl) : (char *)he->str;
if (sflg) {
if (displayhist) {
out2str(s);
}
evalstring(s);
if (displayhist && hist) {
/*
* XXX what about recursive and
* relative histnums.
*/
history(hist, H_ENTER, s);
}
} else
fputs(s, efp);
}
/*
* At end? (if we were to loose last, we'd sure be
* messed up).
*/
if (he->num == last)
break;
}
if (editor) {
char *editcmd;
fclose(efp);
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
sprintf(editcmd, "%s %s", editor, editfile);
evalstring(editcmd); /* XXX - should use no JC command */
INTON;
readcmdfile(editfile); /* XXX - should read back - quick tst */
unlink(editfile);
}
if (lflg == 0 && active > 0)
--active;
if (displayhist)
displayhist = 0;
return 0;
}
STATIC char *
fc_replace(s, p, r)
const char *s;
char *p, *r;
{
char *dest;
int plen = strlen(p);
STARTSTACKSTR(dest);
while (*s) {
if (*s == *p && strncmp(s, p, plen) == 0) {
while (*r)
STPUTC(*r++, dest);
s += plen;
*p = '\0'; /* so no more matches */
} else
STPUTC(*s++, dest);
}
STACKSTRNUL(dest);
dest = grabstackstr(dest);
return (dest);
}
int
not_fcnumber(s)
char *s;
{
if (s == NULL)
return 0;
if (*s == '-')
s++;
return (!is_number(s));
}
int
str_to_event(str, last)
char *str;
int last;
{
const HistEvent *he;
char *s = str;
int relative = 0;
int i;
he = history(hist, H_FIRST);
switch (*s) {
case '-':
relative = 1;
/*FALLTHROUGH*/
case '+':
s++;
}
if (is_number(s)) {
i = atoi(s);
if (relative) {
while (he != NULL && i--) {
he = history(hist, H_NEXT);
}
if (he == NULL)
he = history(hist, H_LAST);
} else {
he = history(hist, H_NEXT_EVENT, i);
if (he == NULL) {
/*
* the notion of first and last is
* backwards to that of the history package
*/
he = history(hist, last ? H_FIRST : H_LAST);
}
}
if (he == NULL)
error("history number %s not found (internal error)",
str);
} else {
/*
* pattern
*/
he = history(hist, H_PREV_STR, str);
if (he == NULL)
error("history pattern not found: %s", str);
}
return (he->num);
}
#else
int
histcmd(argc, argv)
int argc;
char **argv;
{
error("not compiled with history support");
}
#endif

View File

@ -1,43 +0,0 @@
/* $NetBSD: init.h,v 1.8 1995/05/11 21:29:14 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)init.h 8.2 (Berkeley) 5/4/95
*/
void init __P((void));
void reset __P((void));
void initshellproc __P((void));

View File

@ -1,516 +0,0 @@
/* $NetBSD: input.c,v 1.27 1997/07/04 21:02:03 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95";
#else
__RCSID("$NetBSD: input.c,v 1.27 1997/07/04 21:02:03 christos Exp $");
#endif
#endif /* not lint */
#include <stdio.h> /* defines BUFSIZ */
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*
* This file implements the input routines used by the parser.
*/
#include "shell.h"
#include "redir.h"
#include "syntax.h"
#include "input.h"
#include "output.h"
#include "options.h"
#include "memalloc.h"
#include "error.h"
#include "alias.h"
#include "parser.h"
#include "myhistedit.h"
#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
MKINIT
struct strpush {
struct strpush *prev; /* preceding string on stack */
char *prevstring;
int prevnleft;
int prevlleft;
struct alias *ap; /* if push was associated with an alias */
};
/*
* The parsefile structure pointed to by the global variable parsefile
* contains information about the current file being read.
*/
MKINIT
struct parsefile {
struct parsefile *prev; /* preceding file on stack */
int linno; /* current line */
int fd; /* file descriptor (or -1 if string) */
int nleft; /* number of chars left in this line */
int lleft; /* number of chars left in this buffer */
char *nextc; /* next char in buffer */
char *buf; /* input buffer */
struct strpush *strpush; /* for pushing strings at this level */
struct strpush basestrpush; /* so pushing one is fast */
};
int plinno = 1; /* input line number */
MKINIT int parsenleft; /* copy of parsefile->nleft */
MKINIT int parselleft; /* copy of parsefile->lleft */
char *parsenextc; /* copy of parsefile->nextc */
MKINIT struct parsefile basepf; /* top level input file */
char basebuf[BUFSIZ]; /* buffer for top level input file */
struct parsefile *parsefile = &basepf; /* current input file */
int init_editline = 0; /* editline library initialized? */
int whichprompt; /* 1 == PS1, 2 == PS2 */
EditLine *el; /* cookie for editline package */
STATIC void pushfile __P((void));
static int preadfd __P((void));
#ifdef mkinit
INCLUDE "input.h"
INCLUDE "error.h"
INIT {
extern char basebuf[];
basepf.nextc = basepf.buf = basebuf;
}
RESET {
if (exception != EXSHELLPROC)
parselleft = parsenleft = 0; /* clear input buffer */
popallfiles();
}
SHELLPROC {
popallfiles();
}
#endif
/*
* Read a line from the script.
*/
char *
pfgets(line, len)
char *line;
int len;
{
char *p = line;
int nleft = len;
int c;
while (--nleft > 0) {
c = pgetc_macro();
if (c == PEOF) {
if (p == line)
return NULL;
break;
}
*p++ = c;
if (c == '\n')
break;
}
*p = '\0';
return line;
}
/*
* Read a character from the script, returning PEOF on end of file.
* Nul characters in the input are silently discarded.
*/
int
pgetc()
{
return pgetc_macro();
}
static int
preadfd()
{
int nr;
parsenextc = parsefile->buf;
retry:
#ifndef SMALL
if (parsefile->fd == 0 && el) {
const char *rl_cp;
rl_cp = el_gets(el, &nr);
if (rl_cp == NULL)
nr = 0;
else {
/* XXX - BUFSIZE should redesign so not necessary */
(void) strcpy(parsenextc, rl_cp);
}
} else
#endif
nr = read(parsefile->fd, parsenextc, BUFSIZ - 1);
if (nr <= 0) {
if (nr < 0) {
if (errno == EINTR)
goto retry;
if (parsefile->fd == 0 && errno == EWOULDBLOCK) {
int flags = fcntl(0, F_GETFL, 0);
if (flags >= 0 && flags & O_NONBLOCK) {
flags &=~ O_NONBLOCK;
if (fcntl(0, F_SETFL, flags) >= 0) {
out2str("sh: turning off NDELAY mode\n");
goto retry;
}
}
}
}
nr = -1;
}
return nr;
}
/*
* Refill the input buffer and return the next input character:
*
* 1) If a string was pushed back on the input, pop it;
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
* from a string so we can't refill the buffer, return EOF.
* 3) If the is more stuff in this buffer, use it else call read to fill it.
* 4) Process input up to the next newline, deleting nul characters.
*/
int
preadbuffer()
{
char *p, *q;
int more;
int something;
extern EditLine *el;
char savec;
if (parsefile->strpush) {
popstring();
if (--parsenleft >= 0)
return (*parsenextc++);
}
if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
return PEOF;
flushout(&output);
flushout(&errout);
again:
if (parselleft <= 0) {
if ((parselleft = preadfd()) == -1) {
parselleft = parsenleft = EOF_NLEFT;
return PEOF;
}
}
q = p = parsenextc;
/* delete nul characters */
something = 0;
for (more = 1; more;) {
switch (*p) {
case '\0':
p++; /* Skip nul */
goto check;
case '\t':
case ' ':
break;
case '\n':
parsenleft = q - parsenextc;
more = 0; /* Stop processing here */
break;
default:
something = 1;
break;
}
*q++ = *p++;
check:
if (--parselleft <= 0) {
parsenleft = q - parsenextc - 1;
if (parsenleft < 0)
goto again;
*q = '\0';
more = 0;
}
}
savec = *q;
*q = '\0';
#ifndef SMALL
if (parsefile->fd == 0 && hist && something) {
INTOFF;
history(hist, whichprompt == 1 ? H_ENTER : H_ADD, parsenextc);
INTON;
}
#endif
if (vflag) {
out2str(parsenextc);
flushout(out2);
}
*q = savec;
return *parsenextc++;
}
/*
* Undo the last call to pgetc. Only one character may be pushed back.
* PEOF may be pushed back.
*/
void
pungetc() {
parsenleft++;
parsenextc--;
}
/*
* Push a string back onto the input at this current parsefile level.
* We handle aliases this way.
*/
void
pushstring(s, len, ap)
char *s;
int len;
void *ap;
{
struct strpush *sp;
INTOFF;
/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
if (parsefile->strpush) {
sp = ckmalloc(sizeof (struct strpush));
sp->prev = parsefile->strpush;
parsefile->strpush = sp;
} else
sp = parsefile->strpush = &(parsefile->basestrpush);
sp->prevstring = parsenextc;
sp->prevnleft = parsenleft;
sp->prevlleft = parselleft;
sp->ap = (struct alias *)ap;
if (ap)
((struct alias *)ap)->flag |= ALIASINUSE;
parsenextc = s;
parsenleft = len;
INTON;
}
void
popstring()
{
struct strpush *sp = parsefile->strpush;
INTOFF;
parsenextc = sp->prevstring;
parsenleft = sp->prevnleft;
parselleft = sp->prevlleft;
/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
if (sp->ap)
sp->ap->flag &= ~ALIASINUSE;
parsefile->strpush = sp->prev;
if (sp != &(parsefile->basestrpush))
ckfree(sp);
INTON;
}
/*
* Set the input to take input from a file. If push is set, push the
* old input onto the stack first.
*/
void
setinputfile(fname, push)
char *fname;
int push;
{
int fd;
int fd2;
INTOFF;
if ((fd = open(fname, O_RDONLY)) < 0)
error("Can't open %s", fname);
if (fd < 10) {
fd2 = copyfd(fd, 10);
close(fd);
if (fd2 < 0)
error("Out of file descriptors");
fd = fd2;
}
setinputfd(fd, push);
INTON;
}
/*
* Like setinputfile, but takes an open file descriptor. Call this with
* interrupts off.
*/
void
setinputfd(fd, push)
int fd, push;
{
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
if (push) {
pushfile();
parsefile->buf = ckmalloc(BUFSIZ);
}
if (parsefile->fd > 0)
close(parsefile->fd);
parsefile->fd = fd;
if (parsefile->buf == NULL)
parsefile->buf = ckmalloc(BUFSIZ);
parselleft = parsenleft = 0;
plinno = 1;
}
/*
* Like setinputfile, but takes input from a string.
*/
void
setinputstring(string, push)
char *string;
int push;
{
INTOFF;
if (push)
pushfile();
parsenextc = string;
parselleft = parsenleft = strlen(string);
parsefile->buf = NULL;
plinno = 1;
INTON;
}
/*
* To handle the "." command, a stack of input files is used. Pushfile
* adds a new entry to the stack and popfile restores the previous level.
*/
STATIC void
pushfile() {
struct parsefile *pf;
parsefile->nleft = parsenleft;
parsefile->lleft = parselleft;
parsefile->nextc = parsenextc;
parsefile->linno = plinno;
pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
pf->prev = parsefile;
pf->fd = -1;
pf->strpush = NULL;
pf->basestrpush.prev = NULL;
parsefile = pf;
}
void
popfile() {
struct parsefile *pf = parsefile;
INTOFF;
if (pf->fd >= 0)
close(pf->fd);
if (pf->buf)
ckfree(pf->buf);
while (pf->strpush)
popstring();
parsefile = pf->prev;
ckfree(pf);
parsenleft = parsefile->nleft;
parselleft = parsefile->lleft;
parsenextc = parsefile->nextc;
plinno = parsefile->linno;
INTON;
}
/*
* Return to top level.
*/
void
popallfiles() {
while (parsefile != &basepf)
popfile();
}
/*
* Close the file(s) that the shell is reading commands from. Called
* after a fork is done.
*/
void
closescript() {
popallfiles();
if (parsefile->fd > 0) {
close(parsefile->fd);
parsefile->fd = 0;
}
}

View File

@ -1,66 +0,0 @@
/* $NetBSD: input.h,v 1.9 1996/10/16 15:45:09 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)input.h 8.2 (Berkeley) 5/4/95
*/
/* PEOF (the end of file marker) is defined in syntax.h */
/*
* The input line number. Input.c just defines this variable, and saves
* and restores it when files are pushed and popped. The user of this
* package must set its value.
*/
extern int plinno;
extern int parsenleft; /* number of characters left in input buffer */
extern char *parsenextc; /* next character in input buffer */
extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */
char *pfgets __P((char *, int));
int pgetc __P((void));
int preadbuffer __P((void));
void pungetc __P((void));
void pushstring __P((char *, int, void *));
void popstring __P((void));
void setinputfile __P((char *, int));
void setinputfd __P((int, int));
void setinputstring __P((char *, int));
void popfile __P((void));
void popallfiles __P((void));
void closescript __P((void));
#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +0,0 @@
/* $NetBSD: jobs.h,v 1.8 1995/05/11 21:29:19 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)jobs.h 8.2 (Berkeley) 5/4/95
*/
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
#define FORK_FG 0
#define FORK_BG 1
#define FORK_NOJOB 2
/*
* A job structure contains information about a job. A job is either a
* single process or a set of processes contained in a pipeline. In the
* latter case, pidlist will be non-NULL, and will point to a -1 terminated
* array of pids.
*/
struct procstat {
short pid; /* process id */
short status; /* status flags (defined above) */
char *cmd; /* text of command being run */
};
/* states */
#define JOBSTOPPED 1 /* all procs are stopped */
#define JOBDONE 2 /* all procs are completed */
struct job {
struct procstat ps0; /* status of process */
struct procstat *ps; /* status or processes when more than one */
short nprocs; /* number of processes */
short pgrp; /* process group of this job */
char state; /* true if job is finished */
char used; /* true if this entry is in used */
char changed; /* true if status has changed */
#if JOBS
char jobctl; /* job running under job control */
#endif
};
extern short backgndpid; /* pid of last background process */
extern int job_warning; /* user was warned about stopped jobs */
void setjobctl __P((int));
int fgcmd __P((int, char **));
int bgcmd __P((int, char **));
int jobscmd __P((int, char **));
void showjobs __P((int));
int waitcmd __P((int, char **));
int jobidcmd __P((int, char **));
struct job *makejob __P((union node *, int));
int forkshell __P((struct job *, union node *, int));
int waitforjob __P((struct job *));
int stoppedjobs __P((void));
char *commandtext __P((union node *));
#if ! JOBS
#define setjobctl(on) /* do nothing */
#endif

View File

@ -1,53 +0,0 @@
/* $NetBSD: machdep.h,v 1.8 1995/05/11 21:29:21 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)machdep.h 8.2 (Berkeley) 5/4/95
*/
/*
* Most machines require the value returned from malloc to be aligned
* in some way. The following macro will get this right on many machines.
*/
#ifndef ALIGN
union align {
int i;
char *cp;
};
#define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
#endif

View File

@ -1,124 +0,0 @@
/* $NetBSD: mail.c,v 1.11 1997/07/04 21:02:06 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: mail.c,v 1.11 1997/07/04 21:02:06 christos Exp $");
#endif
#endif /* not lint */
/*
* Routines to check for mail. (Perhaps make part of main.c?)
*/
#include "shell.h"
#include "exec.h" /* defines padvance() */
#include "var.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "mail.h"
#include <sys/types.h>
#include <sys/stat.h>
#define MAXMBOXES 10
STATIC int nmboxes; /* number of mailboxes */
STATIC time_t mailtime[MAXMBOXES]; /* times of mailboxes */
/*
* Print appropriate message(s) if mail has arrived. If the argument is
* nozero, then the value of MAIL has changed, so we just update the
* values.
*/
void
chkmail(silent)
int silent;
{
int i;
char *mpath;
char *p;
char *q;
struct stackmark smark;
struct stat statb;
if (silent)
nmboxes = 10;
if (nmboxes == 0)
return;
setstackmark(&smark);
mpath = mpathset()? mpathval() : mailval();
for (i = 0 ; i < nmboxes ; i++) {
p = padvance(&mpath, nullstr);
if (p == NULL)
break;
if (*p == '\0')
continue;
for (q = p ; *q ; q++);
if (q[-1] != '/')
abort();
q[-1] = '\0'; /* delete trailing '/' */
#ifdef notdef /* this is what the System V shell claims to do (it lies) */
if (stat(p, &statb) < 0)
statb.st_mtime = 0;
if (statb.st_mtime > mailtime[i] && ! silent) {
out2str(pathopt? pathopt : "you have mail");
out2c('\n');
}
mailtime[i] = statb.st_mtime;
#else /* this is what it should do */
if (stat(p, &statb) < 0)
statb.st_size = 0;
if (statb.st_size > mailtime[i] && ! silent) {
out2str(pathopt? pathopt : "you have mail");
out2c('\n');
}
mailtime[i] = statb.st_size;
#endif
}
nmboxes = i;
popstackmark(&smark);
}

View File

@ -1,41 +0,0 @@
/* $NetBSD: mail.h,v 1.8 1995/05/11 21:29:23 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mail.h 8.2 (Berkeley) 5/4/95
*/
void chkmail __P((int));

View File

@ -1,388 +0,0 @@
/* $NetBSD: main.c,v 1.26 1997/07/04 21:02:07 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95";
#else
__RCSID("$NetBSD: main.c,v 1.26 1997/07/04 21:02:07 christos Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "shell.h"
#include "main.h"
#include "mail.h"
#include "options.h"
#include "output.h"
#include "parser.h"
#include "nodes.h"
#include "expand.h"
#include "eval.h"
#include "jobs.h"
#include "input.h"
#include "trap.h"
#include "var.h"
#include "show.h"
#include "memalloc.h"
#include "error.h"
#include "init.h"
#include "mystring.h"
#include "exec.h"
#include "cd.h"
#define PROFILE 0
int rootpid;
int rootshell;
STATIC union node *curcmd;
STATIC union node *prevcmd;
extern int errno;
#if PROFILE
short profile_buf[16384];
extern int etext();
#endif
STATIC void read_profile __P((char *));
STATIC char *find_dot_file __P((char *));
int main __P((int, char **));
/*
* Main routine. We initialize things, parse the arguments, execute
* profiles if we're a login shell, and then call cmdloop to execute
* commands. The setjmp call sets up the location to jump to when an
* exception occurs. When an exception occurs the variable "state"
* is used to figure out how far we had gotten.
*/
int
main(argc, argv)
int argc;
char **argv;
{
struct jmploc jmploc;
struct stackmark smark;
volatile int state;
char *shinit;
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
state = 0;
if (setjmp(jmploc.loc)) {
/*
* When a shell procedure is executed, we raise the
* exception EXSHELLPROC to clean up before executing
* the shell procedure.
*/
switch (exception) {
case EXSHELLPROC:
rootpid = getpid();
rootshell = 1;
minusc = NULL;
state = 3;
break;
case EXEXEC:
exitstatus = exerrno;
break;
case EXERROR:
exitstatus = 2;
break;
default:
break;
}
if (exception != EXSHELLPROC) {
if (state == 0 || iflag == 0 || ! rootshell)
exitshell(exitstatus);
}
reset();
if (exception == EXINT
#if ATTY
&& (! attyset() || equal(termval(), "emacs"))
#endif
) {
out2c('\n');
flushout(&errout);
}
popstackmark(&smark);
FORCEINTON; /* enable interrupts */
if (state == 1)
goto state1;
else if (state == 2)
goto state2;
else if (state == 3)
goto state3;
else
goto state4;
}
handler = &jmploc;
#ifdef DEBUG
opentrace();
trputs("Shell args: "); trargs(argv);
#endif
rootpid = getpid();
rootshell = 1;
init();
setstackmark(&smark);
procargs(argc, argv);
if (argv[0] && argv[0][0] == '-') {
state = 1;
read_profile("/etc/profile");
state1:
state = 2;
read_profile(".profile");
}
state2:
state = 3;
if (getuid() == geteuid() && getgid() == getegid()) {
if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
state = 3;
read_profile(shinit);
}
}
state3:
state = 4;
if (minusc) {
evalstring(minusc);
}
if (sflag || minusc == NULL) {
state4: /* XXX ??? - why isn't this before the "if" statement */
cmdloop(1);
}
#if PROFILE
monitor(0);
#endif
exitshell(exitstatus);
/*NOTREACHED*/
return 0;
}
/*
* Read and execute commands. "Top" is nonzero for the top level command
* loop; it turns on prompting if the shell is interactive.
*/
void
cmdloop(top)
int top;
{
union node *n;
struct stackmark smark;
int inter;
int numeof = 0;
TRACE(("cmdloop(%d) called\n", top));
setstackmark(&smark);
for (;;) {
if (pendingsigs)
dotrap();
inter = 0;
if (iflag && top) {
inter++;
showjobs(1);
chkmail(0);
flushout(&output);
}
n = parsecmd(inter);
/* showtree(n); DEBUG */
if (n == NEOF) {
if (!top || numeof >= 50)
break;
if (!stoppedjobs()) {
if (!Iflag)
break;
out2str("\nUse \"exit\" to leave shell.\n");
}
numeof++;
} else if (n != NULL && nflag == 0) {
job_warning = (job_warning == 2) ? 1 : 0;
numeof = 0;
evaltree(n, 0);
}
popstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
break;
}
}
popstackmark(&smark); /* unnecessary */
}
/*
* Read /etc/profile or .profile. Return on error.
*/
STATIC void
read_profile(name)
char *name;
{
int fd;
INTOFF;
if ((fd = open(name, O_RDONLY)) >= 0)
setinputfd(fd, 1);
INTON;
if (fd < 0)
return;
cmdloop(0);
popfile();
}
/*
* Read a file containing shell functions.
*/
void
readcmdfile(name)
char *name;
{
int fd;
INTOFF;
if ((fd = open(name, O_RDONLY)) >= 0)
setinputfd(fd, 1);
else
error("Can't open %s", name);
INTON;
cmdloop(0);
popfile();
}
/*
* Take commands from a file. To be compatable we should do a path
* search for the file, which is necessary to find sub-commands.
*/
STATIC char *
find_dot_file(basename)
char *basename;
{
static char localname[FILENAME_MAX+1];
char *fullname;
char *path = pathval();
struct stat statb;
/* don't try this for absolute or relative paths */
if( strchr(basename, '/'))
return basename;
while ((fullname = padvance(&path, basename)) != NULL) {
strcpy(localname, fullname);
stunalloc(fullname);
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode))
return localname;
}
return basename;
}
int
dotcmd(argc, argv)
int argc;
char **argv;
{
struct strlist *sp;
exitstatus = 0;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
if (argc >= 2) { /* That's what SVR2 does */
char *fullname = find_dot_file(argv[1]);
setinputfile(fullname, 1);
commandname = fullname;
cmdloop(0);
popfile();
}
return exitstatus;
}
int
exitcmd(argc, argv)
int argc;
char **argv;
{
extern int oexitstatus;
if (stoppedjobs())
return 0;
if (argc > 1)
exitstatus = number(argv[1]);
else
exitstatus = oexitstatus;
exitshell(exitstatus);
/*NOTREACHED*/
return 0;
}
#ifdef notdef
/*
* Should never be called.
*/
void
exit(exitstatus) {
_exit(exitstatus);
}
#endif

View File

@ -1,47 +0,0 @@
/* $NetBSD: main.h,v 1.8 1995/05/11 21:29:27 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)main.h 8.2 (Berkeley) 5/4/95
*/
extern int rootpid; /* pid of main shell */
extern int rootshell; /* true if we aren't a child of the main shell */
void readcmdfile __P((char *));
void cmdloop __P((int));
int dotcmd __P((int, char **));
int exitcmd __P((int, char **));

View File

@ -1,306 +0,0 @@
/* $NetBSD: memalloc.c,v 1.20 1997/07/04 21:02:08 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: memalloc.c,v 1.20 1997/07/04 21:02:08 christos Exp $");
#endif
#endif /* not lint */
#include "shell.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "machdep.h"
#include "mystring.h"
#include <stdlib.h>
#include <unistd.h>
/*
* Like malloc, but returns an error when out of space.
*/
pointer
ckmalloc(nbytes)
int nbytes;
{
pointer p;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
return p;
}
/*
* Same for realloc.
*/
pointer
ckrealloc(p, nbytes)
pointer p;
int nbytes;
{
if ((p = realloc(p, nbytes)) == NULL)
error("Out of space");
return p;
}
/*
* Make a copy of a string in safe storage.
*/
char *
savestr(s)
char *s;
{
char *p;
p = ckmalloc(strlen(s) + 1);
scopy(s, p);
return p;
}
/*
* Parse trees for commands are allocated in lifo order, so we use a stack
* to make this more efficient, and also to avoid all sorts of exception
* handling code to handle interrupts in the middle of a parse.
*
* The size 504 was chosen because the Ultrix malloc handles that size
* well.
*/
#define MINSIZE 504 /* minimum size of a block */
struct stack_block {
struct stack_block *prev;
char space[MINSIZE];
};
struct stack_block stackbase;
struct stack_block *stackp = &stackbase;
char *stacknxt = stackbase.space;
int stacknleft = MINSIZE;
int sstrnleft;
int herefd = -1;
pointer
stalloc(nbytes)
int nbytes;
{
char *p;
nbytes = ALIGN(nbytes);
if (nbytes > stacknleft) {
int blocksize;
struct stack_block *sp;
blocksize = nbytes;
if (blocksize < MINSIZE)
blocksize = MINSIZE;
INTOFF;
sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
sp->prev = stackp;
stacknxt = sp->space;
stacknleft = blocksize;
stackp = sp;
INTON;
}
p = stacknxt;
stacknxt += nbytes;
stacknleft -= nbytes;
return p;
}
void
stunalloc(p)
pointer p;
{
if (p == NULL) { /*DEBUG */
write(2, "stunalloc\n", 10);
abort();
}
stacknleft += stacknxt - (char *)p;
stacknxt = p;
}
void
setstackmark(mark)
struct stackmark *mark;
{
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
}
void
popstackmark(mark)
struct stackmark *mark;
{
struct stack_block *sp;
INTOFF;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
ckfree(sp);
}
stacknxt = mark->stacknxt;
stacknleft = mark->stacknleft;
INTON;
}
/*
* When the parser reads in a string, it wants to stick the string on the
* stack and only adjust the stack pointer when it knows how big the
* string is. Stackblock (defined in stack.h) returns a pointer to a block
* of space on top of the stack and stackblocklen returns the length of
* this block. Growstackblock will grow this space by at least one byte,
* possibly moving it (like realloc). Grabstackblock actually allocates the
* part of the block that has been used.
*/
void
growstackblock() {
char *p;
int newlen = ALIGN(stacknleft * 2 + 100);
char *oldspace = stacknxt;
int oldlen = stacknleft;
struct stack_block *sp;
if (stacknxt == stackp->space && stackp != &stackbase) {
INTOFF;
sp = stackp;
stackp = sp->prev;
sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
sp->prev = stackp;
stackp = sp;
stacknxt = sp->space;
stacknleft = newlen;
INTON;
} else {
p = stalloc(newlen);
memcpy(p, oldspace, oldlen);
stacknxt = p; /* free the space */
stacknleft += newlen; /* we just allocated */
}
}
void
grabstackblock(len)
int len;
{
len = ALIGN(len);
stacknxt += len;
stacknleft -= len;
}
/*
* The following routines are somewhat easier to use that the above.
* The user declares a variable of type STACKSTR, which may be declared
* to be a register. The macro STARTSTACKSTR initializes things. Then
* the user uses the macro STPUTC to add characters to the string. In
* effect, STPUTC(c, p) is the same as *p++ = c except that the stack is
* grown as necessary. When the user is done, she can just leave the
* string there and refer to it using stackblock(). Or she can allocate
* the space for it using grabstackstr(). If it is necessary to allow
* someone else to use the stack temporarily and then continue to grow
* the string, the user should use grabstack to allocate the space, and
* then call ungrabstr(p) to return to the previous mode of operation.
*
* USTPUTC is like STPUTC except that it doesn't check for overflow.
* CHECKSTACKSPACE can be called before USTPUTC to ensure that there
* is space for at least one character.
*/
char *
growstackstr() {
int len = stackblocksize();
if (herefd >= 0 && len >= 1024) {
xwrite(herefd, stackblock(), len);
sstrnleft = len - 1;
return stackblock();
}
growstackblock();
sstrnleft = stackblocksize() - len - 1;
return stackblock() + len;
}
/*
* Called from CHECKSTRSPACE.
*/
char *
makestrspace() {
int len = stackblocksize() - sstrnleft;
growstackblock();
sstrnleft = stackblocksize() - len;
return stackblock() + len;
}
void
ungrabstackstr(s, p)
char *s;
char *p;
{
stacknleft += stacknxt - s;
stacknxt = s;
sstrnleft = stacknleft - (p - s);
}

View File

@ -1,80 +0,0 @@
/* $NetBSD: memalloc.h,v 1.10 1995/05/11 21:29:31 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)memalloc.h 8.2 (Berkeley) 5/4/95
*/
struct stackmark {
struct stack_block *stackp;
char *stacknxt;
int stacknleft;
};
extern char *stacknxt;
extern int stacknleft;
extern int sstrnleft;
extern int herefd;
pointer ckmalloc __P((int));
pointer ckrealloc __P((pointer, int));
char *savestr __P((char *));
pointer stalloc __P((int));
void stunalloc __P((pointer));
void setstackmark __P((struct stackmark *));
void popstackmark __P((struct stackmark *));
void growstackblock __P((void));
void grabstackblock __P((int));
char *growstackstr __P((void));
char *makestrspace __P((void));
void ungrabstackstr __P((char *, char *));
#define stackblock() stacknxt
#define stackblocksize() stacknleft
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); }
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
#define STUNPUTC(p) (++sstrnleft, --p)
#define STTOPC(p) p[-1]
#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
#define ckfree(p) free((pointer)(p))

View File

@ -1,402 +0,0 @@
/* $NetBSD: miscbltin.c,v 1.19 1997/07/04 21:02:09 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: miscbltin.c,v 1.19 1997/07/04 21:02:09 christos Exp $");
#endif
#endif /* not lint */
/*
* Miscelaneous builtins.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <ctype.h>
#include "shell.h"
#include "options.h"
#include "var.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "miscbltin.h"
#include "mystring.h"
#undef eflag
extern char **argptr; /* argument list for builtin command */
/*
* The read builtin. The -e option causes backslashes to escape the
* following character.
*
* This uses unbuffered input, which may be avoidable in some cases.
*/
int
readcmd(argc, argv)
int argc;
char **argv;
{
char **ap;
int backslash;
char c;
int eflag;
char *prompt;
char *ifs;
char *p;
int startword;
int status;
int i;
eflag = 0;
prompt = NULL;
while ((i = nextopt("ep:")) != '\0') {
if (i == 'p')
prompt = optarg;
else
eflag = 1;
}
if (prompt && isatty(0)) {
out2str(prompt);
flushall();
}
if (*(ap = argptr) == NULL)
error("arg count");
if ((ifs = bltinlookup("IFS", 1)) == NULL)
ifs = nullstr;
status = 0;
startword = 1;
backslash = 0;
STARTSTACKSTR(p);
for (;;) {
if (read(0, &c, 1) != 1) {
status = 1;
break;
}
if (c == '\0')
continue;
if (backslash) {
backslash = 0;
if (c != '\n')
STPUTC(c, p);
continue;
}
if (eflag && c == '\\') {
backslash++;
continue;
}
if (c == '\n')
break;
if (startword && *ifs == ' ' && strchr(ifs, c)) {
continue;
}
startword = 0;
if (backslash && c == '\\') {
if (read(0, &c, 1) != 1) {
status = 1;
break;
}
STPUTC(c, p);
} else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
STACKSTRNUL(p);
setvar(*ap, stackblock(), 0);
ap++;
startword = 1;
STARTSTACKSTR(p);
} else {
STPUTC(c, p);
}
}
STACKSTRNUL(p);
setvar(*ap, stackblock(), 0);
while (*++ap != NULL)
setvar(*ap, nullstr, 0);
return status;
}
int
umaskcmd(argc, argv)
int argc;
char **argv;
{
char *ap;
int mask;
int i;
int symbolic_mode = 0;
while ((i = nextopt("S")) != '\0') {
symbolic_mode = 1;
}
INTOFF;
mask = umask(0);
umask(mask);
INTON;
if ((ap = *argptr) == NULL) {
if (symbolic_mode) {
char u[4], g[4], o[4];
i = 0;
if ((mask & S_IRUSR) == 0)
u[i++] = 'r';
if ((mask & S_IWUSR) == 0)
u[i++] = 'w';
if ((mask & S_IXUSR) == 0)
u[i++] = 'x';
u[i] = '\0';
i = 0;
if ((mask & S_IRGRP) == 0)
g[i++] = 'r';
if ((mask & S_IWGRP) == 0)
g[i++] = 'w';
if ((mask & S_IXGRP) == 0)
g[i++] = 'x';
g[i] = '\0';
i = 0;
if ((mask & S_IROTH) == 0)
o[i++] = 'r';
if ((mask & S_IWOTH) == 0)
o[i++] = 'w';
if ((mask & S_IXOTH) == 0)
o[i++] = 'x';
o[i] = '\0';
out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
} else {
out1fmt("%.4o\n", mask);
}
} else {
if (isdigit(*ap)) {
mask = 0;
do {
if (*ap >= '8' || *ap < '0')
error("Illegal number: %s", argv[1]);
mask = (mask << 3) + (*ap - '0');
} while (*++ap != '\0');
umask(mask);
} else {
void *set;
if ((set = setmode (ap)) == 0)
error("Illegal number: %s", ap);
mask = getmode (set, ~mask & 0777);
umask(~mask & 0777);
}
}
return 0;
}
/*
* ulimit builtin
*
* This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
* Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
* ash by J.T. Conklin.
*
* Public domain.
*/
struct limits {
const char *name;
int cmd;
int factor; /* multiply by to get rlim_{cur,max} values */
char option;
};
static const struct limits limits[] = {
#ifdef RLIMIT_CPU
{ "time(seconds)", RLIMIT_CPU, 1, 't' },
#endif
#ifdef RLIMIT_FSIZE
{ "file(blocks)", RLIMIT_FSIZE, 512, 'f' },
#endif
#ifdef RLIMIT_DATA
{ "data(kbytes)", RLIMIT_DATA, 1024, 'd' },
#endif
#ifdef RLIMIT_STACK
{ "stack(kbytes)", RLIMIT_STACK, 1024, 's' },
#endif
#ifdef RLIMIT_CORE
{ "coredump(blocks)", RLIMIT_CORE, 512, 'c' },
#endif
#ifdef RLIMIT_RSS
{ "memory(kbytes)", RLIMIT_RSS, 1024, 'm' },
#endif
#ifdef RLIMIT_MEMLOCK
{ "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' },
#endif
#ifdef RLIMIT_NPROC
{ "process(processes)", RLIMIT_NPROC, 1, 'p' },
#endif
#ifdef RLIMIT_NOFILE
{ "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' },
#endif
#ifdef RLIMIT_VMEM
{ "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' },
#endif
#ifdef RLIMIT_SWAP
{ "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' },
#endif
{ (char *) 0, 0, 0, '\0' }
};
int
ulimitcmd(argc, argv)
int argc;
char **argv;
{
int c;
rlim_t val = 0;
enum { SOFT = 0x1, HARD = 0x2 }
how = SOFT | HARD;
const struct limits *l;
int set, all = 0;
int optc, what;
struct rlimit limit;
what = 'f';
while ((optc = nextopt("HSatfdsmcnpl")) != '\0')
switch (optc) {
case 'H':
how = HARD;
break;
case 'S':
how = SOFT;
break;
case 'a':
all = 1;
break;
default:
what = optc;
}
for (l = limits; l->name && l->option != what; l++)
;
if (!l->name)
error("ulimit: internal error (%c)\n", what);
set = *argptr ? 1 : 0;
if (set) {
char *p = *argptr;
if (all || argptr[1])
error("ulimit: too many arguments\n");
if (strcmp(p, "unlimited") == 0)
val = RLIM_INFINITY;
else {
val = (rlim_t) 0;
while ((c = *p++) >= '0' && c <= '9')
{
val = (val * 10) + (long)(c - '0');
if (val < (rlim_t) 0)
break;
}
if (c)
error("ulimit: bad number\n");
val *= l->factor;
}
}
if (all) {
for (l = limits; l->name; l++) {
getrlimit(l->cmd, &limit);
if (how & SOFT)
val = limit.rlim_cur;
else if (how & HARD)
val = limit.rlim_max;
out1fmt("%-20s ", l->name);
if (val == RLIM_INFINITY)
out1fmt("unlimited\n");
else
{
val /= l->factor;
#ifdef BSD4_4
out1fmt("%qd\n", (quad_t) val);
#else
out1fmt("%ld\n", (long) val);
#endif
}
}
return 0;
}
getrlimit(l->cmd, &limit);
if (set) {
if (how & SOFT)
limit.rlim_cur = val;
if (how & HARD)
limit.rlim_max = val;
if (setrlimit(l->cmd, &limit) < 0)
error("ulimit: bad limit\n");
} else {
if (how & SOFT)
val = limit.rlim_cur;
else if (how & HARD)
val = limit.rlim_max;
if (val == RLIM_INFINITY)
out1fmt("unlimited\n");
else
{
val /= l->factor;
#ifdef BSD4_4
out1fmt("%qd\n", (quad_t) val);
#else
out1fmt("%ld\n", (long) val);
#endif
}
}
return 0;
}

View File

@ -1,34 +0,0 @@
/* $NetBSD: miscbltin.h,v 1.1 1997/07/04 21:02:10 christos Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christos Zoulas.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
int readcmd __P((int, char **));
int umaskcmd __P((int, char **));
int ulimitcmd __P((int, char **));

View File

@ -1,94 +0,0 @@
#!/bin/sh -
# $NetBSD: mkbuiltins,v 1.13 1997/07/04 21:02:10 christos Exp $
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mkbuiltins 8.2 (Berkeley) 5/4/95
temp=/tmp/ka$$
havejobs=0
if grep '^#define JOBS[ ]*1' shell.h > /dev/null
then havejobs=1
fi
havehist=1
if [ "X$1" = "X-h" ]; then
havehist=0
shift
fi
objdir=$1
exec > ${objdir}/builtins.c
cat <<\!
/*
* This file was generated by the mkbuiltins program.
*/
#include "shell.h"
#include "builtins.h"
!
awk '/^[^#]/ {if(('$havejobs' || $2 != "-j") && ('$havehist' || $2 != "-h")) \
print $0}' builtins.def | sed 's/-j//' > $temp
awk '{ printf "int %s __P((int, char **));\n", $1}' $temp
echo '
int (*const builtinfunc[]) __P((int, char **)) = {'
awk '/^[^#]/ { printf "\t%s,\n", $1}' $temp
echo '};
const struct builtincmd builtincmd[] = {'
awk '{ for (i = 2 ; i <= NF ; i++) {
printf "\t{ \"%s\", %d },\n", $i, NR-1
}}' $temp
echo ' { NULL, 0 }
};'
exec > ${objdir}/builtins.h
cat <<\!
/*
* This file was generated by the mkbuiltins program.
*/
#include <sys/cdefs.h>
!
tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ < $temp |
awk '{ printf "#define %s %d\n", $1, NR-1}'
echo '
struct builtincmd {
char *name;
int code;
};
extern int (*const builtinfunc[]) __P((int, char **));
extern const struct builtincmd builtincmd[];'
rm -f $temp

View File

@ -1,523 +0,0 @@
/* $NetBSD: mkinit.c,v 1.17 1997/07/04 21:02:11 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)mkinit.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: mkinit.c,v 1.17 1997/07/04 21:02:11 christos Exp $");
#endif
#endif /* not lint */
/*
* This program scans all the source files for code to handle various
* special events and combines this code into one file. This (allegedly)
* improves the structure of the program since there is no need for
* anyone outside of a module to know that that module performs special
* operations on particular events.
*
* Usage: mkinit sourcefile...
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
/*
* OUTFILE is the name of the output file. Output is initially written
* to the file OUTTEMP, which is then moved to OUTFILE.
*/
#define OUTFILE "init.c"
#define OUTTEMP "init.c.new"
/*
* A text structure is basicly just a string that grows as more characters
* are added onto the end of it. It is implemented as a linked list of
* blocks of characters. The routines addstr and addchar append a string
* or a single character, respectively, to a text structure. Writetext
* writes the contents of a text structure to a file.
*/
#define BLOCKSIZE 512
struct text {
char *nextc;
int nleft;
struct block *start;
struct block *last;
};
struct block {
struct block *next;
char text[BLOCKSIZE];
};
/*
* There is one event structure for each event that mkinit handles.
*/
struct event {
char *name; /* name of event (e.g. INIT) */
char *routine; /* name of routine called on event */
char *comment; /* comment describing routine */
struct text code; /* code for handling event */
};
char writer[] = "\
/*\n\
* This file was generated by the mkinit program.\n\
*/\n\
\n";
char init[] = "\
/*\n\
* Initialization code.\n\
*/\n";
char reset[] = "\
/*\n\
* This routine is called when an error or an interrupt occurs in an\n\
* interactive shell and control is returned to the main command loop.\n\
*/\n";
char shellproc[] = "\
/*\n\
* This routine is called to initialize the shell to run a shell procedure.\n\
*/\n";
struct event event[] = {
{"INIT", "init", init},
{"RESET", "reset", reset},
{"SHELLPROC", "initshellproc", shellproc},
{NULL, NULL}
};
char *curfile; /* current file */
int linno; /* current line */
char *header_files[200]; /* list of header files */
struct text defines; /* #define statements */
struct text decls; /* declarations */
int amiddecls; /* for formatting */
void readfile __P((char *));
int match __P((char *, char *));
int gooddefine __P((char *));
void doevent __P((struct event *, FILE *, char *));
void doinclude __P((char *));
void dodecl __P((char *, FILE *));
void output __P((void));
void addstr __P((char *, struct text *));
void addchar __P((int, struct text *));
void writetext __P((struct text *, FILE *));
FILE *ckfopen __P((char *, char *));
void *ckmalloc __P((int));
char *savestr __P((char *));
void error __P((char *));
int main __P((int, char **));
#define equal(s1, s2) (strcmp(s1, s2) == 0)
int
main(argc, argv)
int argc;
char **argv;
{
char **ap;
header_files[0] = "\"shell.h\"";
header_files[1] = "\"mystring.h\"";
header_files[2] = "\"init.h\"";
for (ap = argv + 1 ; *ap ; ap++)
readfile(*ap);
output();
rename(OUTTEMP, OUTFILE);
exit(0);
}
/*
* Parse an input file.
*/
void
readfile(fname)
char *fname;
{
FILE *fp;
char line[1024];
struct event *ep;
fp = ckfopen(fname, "r");
curfile = fname;
linno = 0;
amiddecls = 0;
while (fgets(line, sizeof line, fp) != NULL) {
linno++;
for (ep = event ; ep->name ; ep++) {
if (line[0] == ep->name[0] && match(ep->name, line)) {
doevent(ep, fp, fname);
break;
}
}
if (line[0] == 'I' && match("INCLUDE", line))
doinclude(line);
if (line[0] == 'M' && match("MKINIT", line))
dodecl(line, fp);
if (line[0] == '#' && gooddefine(line))
addstr(line, &defines);
if (line[0] == '#' && gooddefine(line)) {
char *cp;
char line2[1024];
static const char undef[] = "#undef ";
strcpy(line2, line);
memcpy(line2, undef, sizeof(undef) - 1);
cp = line2 + sizeof(undef) - 1;
while(*cp && (*cp == ' ' || *cp == '\t'))
cp++;
while(*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
cp++;
*cp++ = '\n'; *cp = '\0';
addstr(line2, &defines);
addstr(line, &defines);
}
}
fclose(fp);
}
int
match(name, line)
char *name;
char *line;
{
char *p, *q;
p = name, q = line;
while (*p) {
if (*p++ != *q++)
return 0;
}
if (*q != '{' && *q != ' ' && *q != '\t' && *q != '\n')
return 0;
return 1;
}
int
gooddefine(line)
char *line;
{
char *p;
if (! match("#define", line))
return 0; /* not a define */
p = line + 7;
while (*p == ' ' || *p == '\t')
p++;
while (*p != ' ' && *p != '\t') {
if (*p == '(')
return 0; /* macro definition */
p++;
}
while (*p != '\n' && *p != '\0')
p++;
if (p[-1] == '\\')
return 0; /* multi-line definition */
return 1;
}
void
doevent(ep, fp, fname)
struct event *ep;
FILE *fp;
char *fname;
{
char line[1024];
int indent;
char *p;
sprintf(line, "\n /* from %s: */\n", fname);
addstr(line, &ep->code);
addstr(" {\n", &ep->code);
for (;;) {
linno++;
if (fgets(line, sizeof line, fp) == NULL)
error("Unexpected EOF");
if (equal(line, "}\n"))
break;
indent = 6;
for (p = line ; *p == '\t' ; p++)
indent += 8;
for ( ; *p == ' ' ; p++)
indent++;
if (*p == '\n' || *p == '#')
indent = 0;
while (indent >= 8) {
addchar('\t', &ep->code);
indent -= 8;
}
while (indent > 0) {
addchar(' ', &ep->code);
indent--;
}
addstr(p, &ep->code);
}
addstr(" }\n", &ep->code);
}
void
doinclude(line)
char *line;
{
char *p;
char *name;
char **pp;
for (p = line ; *p != '"' && *p != '<' && *p != '\0' ; p++);
if (*p == '\0')
error("Expecting '\"' or '<'");
name = p;
while (*p != ' ' && *p != '\t' && *p != '\n')
p++;
if (p[-1] != '"' && p[-1] != '>')
error("Missing terminator");
*p = '\0';
/* name now contains the name of the include file */
for (pp = header_files ; *pp && ! equal(*pp, name) ; pp++);
if (*pp == NULL)
*pp = savestr(name);
}
void
dodecl(line1, fp)
char *line1;
FILE *fp;
{
char line[1024];
char *p, *q;
if (strcmp(line1, "MKINIT\n") == 0) { /* start of struct/union decl */
addchar('\n', &decls);
do {
linno++;
if (fgets(line, sizeof line, fp) == NULL)
error("Unterminated structure declaration");
addstr(line, &decls);
} while (line[0] != '}');
amiddecls = 0;
} else {
if (! amiddecls)
addchar('\n', &decls);
q = NULL;
for (p = line1 + 6 ; *p && strchr("=/\n", *p) == NULL; p++)
continue;
if (*p == '=') { /* eliminate initialization */
for (q = p ; *q && *q != ';' ; q++);
if (*q == '\0')
q = NULL;
else {
while (p[-1] == ' ')
p--;
*p = '\0';
}
}
addstr("extern", &decls);
addstr(line1 + 6, &decls);
if (q != NULL)
addstr(q, &decls);
amiddecls = 1;
}
}
/*
* Write the output to the file OUTTEMP.
*/
void
output() {
FILE *fp;
char **pp;
struct event *ep;
fp = ckfopen(OUTTEMP, "w");
fputs(writer, fp);
for (pp = header_files ; *pp ; pp++)
fprintf(fp, "#include %s\n", *pp);
fputs("\n\n\n", fp);
writetext(&defines, fp);
fputs("\n\n", fp);
writetext(&decls, fp);
for (ep = event ; ep->name ; ep++) {
fputs("\n\n\n", fp);
fputs(ep->comment, fp);
fprintf(fp, "\nvoid\n%s() {\n", ep->routine);
writetext(&ep->code, fp);
fprintf(fp, "}\n");
}
fclose(fp);
}
/*
* A text structure is simply a block of text that is kept in memory.
* Addstr appends a string to the text struct, and addchar appends a single
* character.
*/
void
addstr(s, text)
char *s;
struct text *text;
{
while (*s) {
if (--text->nleft < 0)
addchar(*s++, text);
else
*text->nextc++ = *s++;
}
}
void
addchar(c, text)
int c;
struct text *text;
{
struct block *bp;
if (--text->nleft < 0) {
bp = ckmalloc(sizeof *bp);
if (text->start == NULL)
text->start = bp;
else
text->last->next = bp;
text->last = bp;
text->nextc = bp->text;
text->nleft = BLOCKSIZE - 1;
}
*text->nextc++ = c;
}
/*
* Write the contents of a text structure to a file.
*/
void
writetext(text, fp)
struct text *text;
FILE *fp;
{
struct block *bp;
if (text->start != NULL) {
for (bp = text->start ; bp != text->last ; bp = bp->next)
fwrite(bp->text, sizeof (char), BLOCKSIZE, fp);
fwrite(bp->text, sizeof (char), BLOCKSIZE - text->nleft, fp);
}
}
FILE *
ckfopen(file, mode)
char *file;
char *mode;
{
FILE *fp;
if ((fp = fopen(file, mode)) == NULL) {
fprintf(stderr, "Can't open %s\n", file);
exit(2);
}
return fp;
}
void *
ckmalloc(nbytes)
int nbytes;
{
char *p;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
return p;
}
char *
savestr(s)
char *s;
{
char *p;
p = ckmalloc(strlen(s) + 1);
strcpy(p, s);
return p;
}
void
error(msg)
char *msg;
{
if (curfile != NULL)
fprintf(stderr, "%s:%d: ", curfile, linno);
fprintf(stderr, "%s\n", msg);
exit(2);
}

View File

@ -1,482 +0,0 @@
/* $NetBSD: mknodes.c,v 1.15 1997/07/04 21:02:12 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: mknodes.c,v 1.15 1997/07/04 21:02:12 christos Exp $");
#endif
#endif /* not lint */
/*
* This program reads the nodetypes file and nodes.c.pat file. It generates
* the files nodes.h and nodes.c.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#define MAXTYPES 50 /* max number of node types */
#define MAXFIELDS 20 /* max fields in a structure */
#define BUFLEN 100 /* size of character buffers */
/* field types */
#define T_NODE 1 /* union node *field */
#define T_NODELIST 2 /* struct nodelist *field */
#define T_STRING 3
#define T_INT 4 /* int field */
#define T_OTHER 5 /* other */
#define T_TEMP 6 /* don't copy this field */
struct field { /* a structure field */
char *name; /* name of field */
int type; /* type of field */
char *decl; /* declaration of field */
};
struct str { /* struct representing a node structure */
char *tag; /* structure tag */
int nfields; /* number of fields in the structure */
struct field field[MAXFIELDS]; /* the fields of the structure */
int done; /* set if fully parsed */
};
static int ntypes; /* number of node types */
static char *nodename[MAXTYPES]; /* names of the nodes */
static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
static int nstr; /* number of structures */
static struct str str[MAXTYPES]; /* the structures */
static struct str *curstr; /* current structure */
static FILE *infp = stdin;
static char line[1024];
static int linno;
static char *linep;
static void parsenode __P((void));
static void parsefield __P((void));
static void output __P((char *));
static void outsizes __P((FILE *));
static void outfunc __P((FILE *, int));
static void indent __P((int, FILE *));
static int nextfield __P((char *));
static void skipbl __P((void));
static int readline __P((void));
static void error __P((const char *, ...));
static char *savestr __P((const char *));
int main __P((int, char **));
int
main(argc, argv)
int argc;
char **argv;
{
if (argc != 3)
error("usage: mknodes file");
if ((infp = fopen(argv[1], "r")) == NULL)
error("Can't open %s", argv[1]);
while (readline()) {
if (line[0] == ' ' || line[0] == '\t')
parsefield();
else if (line[0] != '\0')
parsenode();
}
output(argv[2]);
exit(0);
}
static void
parsenode()
{
char name[BUFLEN];
char tag[BUFLEN];
struct str *sp;
if (curstr && curstr->nfields > 0)
curstr->done = 1;
nextfield(name);
if (! nextfield(tag))
error("Tag expected");
if (*linep != '\0')
error("Garbage at end of line");
nodename[ntypes] = savestr(name);
for (sp = str ; sp < str + nstr ; sp++) {
if (strcmp(sp->tag, tag) == 0)
break;
}
if (sp >= str + nstr) {
sp->tag = savestr(tag);
sp->nfields = 0;
curstr = sp;
nstr++;
}
nodestr[ntypes] = sp;
ntypes++;
}
static void
parsefield()
{
char name[BUFLEN];
char type[BUFLEN];
char decl[2 * BUFLEN];
struct field *fp;
if (curstr == NULL || curstr->done)
error("No current structure to add field to");
if (! nextfield(name))
error("No field name");
if (! nextfield(type))
error("No field type");
fp = &curstr->field[curstr->nfields];
fp->name = savestr(name);
if (strcmp(type, "nodeptr") == 0) {
fp->type = T_NODE;
sprintf(decl, "union node *%s", name);
} else if (strcmp(type, "nodelist") == 0) {
fp->type = T_NODELIST;
sprintf(decl, "struct nodelist *%s", name);
} else if (strcmp(type, "string") == 0) {
fp->type = T_STRING;
sprintf(decl, "char *%s", name);
} else if (strcmp(type, "int") == 0) {
fp->type = T_INT;
sprintf(decl, "int %s", name);
} else if (strcmp(type, "other") == 0) {
fp->type = T_OTHER;
} else if (strcmp(type, "temp") == 0) {
fp->type = T_TEMP;
} else {
error("Unknown type %s", type);
}
if (fp->type == T_OTHER || fp->type == T_TEMP) {
skipbl();
fp->decl = savestr(linep);
} else {
if (*linep)
error("Garbage at end of line");
fp->decl = savestr(decl);
}
curstr->nfields++;
}
char writer[] = "\
/*\n\
* This file was generated by the mknodes program.\n\
*/\n\
\n";
static void
output(file)
char *file;
{
FILE *hfile;
FILE *cfile;
FILE *patfile;
int i;
struct str *sp;
struct field *fp;
char *p;
if ((patfile = fopen(file, "r")) == NULL)
error("Can't open %s", file);
if ((hfile = fopen("nodes.h", "w")) == NULL)
error("Can't create nodes.h");
if ((cfile = fopen("nodes.c", "w")) == NULL)
error("Can't create nodes.c");
fputs(writer, hfile);
for (i = 0 ; i < ntypes ; i++)
fprintf(hfile, "#define %s %d\n", nodename[i], i);
fputs("\n\n\n", hfile);
for (sp = str ; sp < &str[nstr] ; sp++) {
fprintf(hfile, "struct %s {\n", sp->tag);
for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) {
fprintf(hfile, " %s;\n", fp->decl);
}
fputs("};\n\n\n", hfile);
}
fputs("union node {\n", hfile);
fprintf(hfile, " int type;\n");
for (sp = str ; sp < &str[nstr] ; sp++) {
fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag);
}
fputs("};\n\n\n", hfile);
fputs("struct nodelist {\n", hfile);
fputs("\tstruct nodelist *next;\n", hfile);
fputs("\tunion node *n;\n", hfile);
fputs("};\n\n\n", hfile);
fputs("#ifdef __STDC__\n", hfile);
fputs("union node *copyfunc(union node *);\n", hfile);
fputs("void freefunc(union node *);\n", hfile);
fputs("#else\n", hfile);
fputs("union node *copyfunc();\n", hfile);
fputs("void freefunc();\n", hfile);
fputs("#endif\n", hfile);
fputs(writer, cfile);
while (fgets(line, sizeof line, patfile) != NULL) {
for (p = line ; *p == ' ' || *p == '\t' ; p++);
if (strcmp(p, "%SIZES\n") == 0)
outsizes(cfile);
else if (strcmp(p, "%CALCSIZE\n") == 0)
outfunc(cfile, 1);
else if (strcmp(p, "%COPY\n") == 0)
outfunc(cfile, 0);
else
fputs(line, cfile);
}
}
static void
outsizes(cfile)
FILE *cfile;
{
int i;
fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes);
for (i = 0 ; i < ntypes ; i++) {
fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag);
}
fprintf(cfile, "};\n");
}
static void
outfunc(cfile, calcsize)
FILE *cfile;
int calcsize;
{
struct str *sp;
struct field *fp;
int i;
fputs(" if (n == NULL)\n", cfile);
if (calcsize)
fputs(" return;\n", cfile);
else
fputs(" return NULL;\n", cfile);
if (calcsize)
fputs(" funcblocksize += nodesize[n->type];\n", cfile);
else {
fputs(" new = funcblock;\n", cfile);
fputs(" funcblock = (char *) funcblock + nodesize[n->type];\n", cfile);
}
fputs(" switch (n->type) {\n", cfile);
for (sp = str ; sp < &str[nstr] ; sp++) {
for (i = 0 ; i < ntypes ; i++) {
if (nodestr[i] == sp)
fprintf(cfile, " case %s:\n", nodename[i]);
}
for (i = sp->nfields ; --i >= 1 ; ) {
fp = &sp->field[i];
switch (fp->type) {
case T_NODE:
if (calcsize) {
indent(12, cfile);
fprintf(cfile, "calcsize(n->%s.%s);\n",
sp->tag, fp->name);
} else {
indent(12, cfile);
fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n",
sp->tag, fp->name, sp->tag, fp->name);
}
break;
case T_NODELIST:
if (calcsize) {
indent(12, cfile);
fprintf(cfile, "sizenodelist(n->%s.%s);\n",
sp->tag, fp->name);
} else {
indent(12, cfile);
fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n",
sp->tag, fp->name, sp->tag, fp->name);
}
break;
case T_STRING:
if (calcsize) {
indent(12, cfile);
fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n",
sp->tag, fp->name);
} else {
indent(12, cfile);
fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n",
sp->tag, fp->name, sp->tag, fp->name);
}
break;
case T_INT:
case T_OTHER:
if (! calcsize) {
indent(12, cfile);
fprintf(cfile, "new->%s.%s = n->%s.%s;\n",
sp->tag, fp->name, sp->tag, fp->name);
}
break;
}
}
indent(12, cfile);
fputs("break;\n", cfile);
}
fputs(" };\n", cfile);
if (! calcsize)
fputs(" new->type = n->type;\n", cfile);
}
static void
indent(amount, fp)
int amount;
FILE *fp;
{
while (amount >= 8) {
putc('\t', fp);
amount -= 8;
}
while (--amount >= 0) {
putc(' ', fp);
}
}
static int
nextfield(buf)
char *buf;
{
char *p, *q;
p = linep;
while (*p == ' ' || *p == '\t')
p++;
q = buf;
while (*p != ' ' && *p != '\t' && *p != '\0')
*q++ = *p++;
*q = '\0';
linep = p;
return (q > buf);
}
static void
skipbl()
{
while (*linep == ' ' || *linep == '\t')
linep++;
}
static int
readline()
{
char *p;
if (fgets(line, 1024, infp) == NULL)
return 0;
for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++);
while (p > line && (p[-1] == ' ' || p[-1] == '\t'))
p--;
*p = '\0';
linep = line;
linno++;
if (p - line > BUFLEN)
error("Line too long");
return 1;
}
static void
#ifdef __STDC__
error(const char *msg, ...)
#else
error(va_alist)
va_dcl
#endif
{
va_list va;
#ifdef __STDC__
va_start(va, msg);
#else
char *msg;
va_start(va);
msg = va_arg(va, char *);
#endif
(void) fprintf(stderr, "line %d: ", linno);
(void) vfprintf(stderr, msg, va);
(void) fputc('\n', stderr);
va_end(va);
exit(2);
}
static char *
savestr(s)
const char *s;
{
char *p;
if ((p = malloc(strlen(s) + 1)) == NULL)
error("Out of space");
(void) strcpy(p, s);
return p;
}

View File

@ -1,407 +0,0 @@
/* $NetBSD: mksyntax.c,v 1.15 1997/07/05 21:25:09 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)mksyntax.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: mksyntax.c,v 1.15 1997/07/05 21:25:09 christos Exp $");
#endif
#endif /* not lint */
/*
* This program creates syntax.h and syntax.c.
*/
#include <stdio.h>
#include <string.h>
#include "parser.h"
struct synclass {
char *name;
char *comment;
};
/* Syntax classes */
struct synclass synclass[] = {
{ "CWORD", "character is nothing special" },
{ "CNL", "newline character" },
{ "CBACK", "a backslash character" },
{ "CSQUOTE", "single quote" },
{ "CDQUOTE", "double quote" },
{ "CENDQUOTE", "a terminating quote" },
{ "CBQUOTE", "backwards single quote" },
{ "CVAR", "a dollar sign" },
{ "CENDVAR", "a '}' character" },
{ "CLP", "a left paren in arithmetic" },
{ "CRP", "a right paren in arithmetic" },
{ "CEOF", "end of file" },
{ "CCTL", "like CWORD, except it must be escaped" },
{ "CSPCL", "these terminate a word" },
{ NULL, NULL }
};
/*
* Syntax classes for is_ functions. Warning: if you add new classes
* you may have to change the definition of the is_in_name macro.
*/
struct synclass is_entry[] = {
{ "ISDIGIT", "a digit" },
{ "ISUPPER", "an upper case letter" },
{ "ISLOWER", "a lower case letter" },
{ "ISUNDER", "an underscore" },
{ "ISSPECL", "the name of a special parameter" },
{ NULL, NULL }
};
static char writer[] = "\
/*\n\
* This file was generated by the mksyntax program.\n\
*/\n\
\n";
static FILE *cfile;
static FILE *hfile;
static char *syntax[513];
static int base;
static int size; /* number of values which a char variable can have */
static int nbits; /* number of bits in a character */
static int digit_contig;/* true if digits are contiguous */
static void filltable __P((char *));
static void init __P((void));
static void add __P((char *, char *));
static void print __P((char *));
static void output_type_macros __P((void));
static void digit_convert __P((void));
int main __P((int, char **));
int
main(argc, argv)
int argc;
char **argv;
{
char c;
char d;
int sign;
int i;
char buf[80];
int pos;
static char digit[] = "0123456789";
/* Create output files */
if ((cfile = fopen("syntax.c", "w")) == NULL) {
perror("syntax.c");
exit(2);
}
if ((hfile = fopen("syntax.h", "w")) == NULL) {
perror("syntax.h");
exit(2);
}
fputs(writer, hfile);
fputs(writer, cfile);
/* Determine the characteristics of chars. */
c = -1;
if (c <= 0)
sign = 1;
else
sign = 0;
for (nbits = 1 ; ; nbits++) {
d = (1 << nbits) - 1;
if (d == c)
break;
}
printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
if (nbits > 9) {
fputs("Characters can't have more than 9 bits\n", stderr);
exit(2);
}
size = (1 << nbits) + 1;
base = 1;
if (sign)
base += 1 << (nbits - 1);
digit_contig = 1;
for (i = 0 ; i < 10 ; i++) {
if (digit[i] != '0' + i)
digit_contig = 0;
}
fputs("#include <sys/cdefs.h>\n", hfile);
fputs("#include <ctype.h>\n", hfile);
/* Generate the #define statements in the header file */
fputs("/* Syntax classes */\n", hfile);
for (i = 0 ; synclass[i].name ; i++) {
sprintf(buf, "#define %s %d", synclass[i].name, i);
fputs(buf, hfile);
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07)
putc('\t', hfile);
fprintf(hfile, "/* %s */\n", synclass[i].comment);
}
putc('\n', hfile);
fputs("/* Syntax classes for is_ functions */\n", hfile);
for (i = 0 ; is_entry[i].name ; i++) {
sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i);
fputs(buf, hfile);
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07)
putc('\t', hfile);
fprintf(hfile, "/* %s */\n", is_entry[i].comment);
}
putc('\n', hfile);
fprintf(hfile, "#define SYNBASE %d\n", base);
fprintf(hfile, "#define PEOF %d\n\n", -base);
if (sign)
fprintf(hfile, "#define UPEOF %d\n\n", -base);
else
fprintf(hfile, "#define UPEOF ((unsigned char) %d)\n\n", -base);
putc('\n', hfile);
fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile);
fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile);
putc('\n', hfile);
output_type_macros(); /* is_digit, etc. */
putc('\n', hfile);
/* Generate the syntax tables. */
fputs("#include \"shell.h\"\n", cfile);
fputs("#include \"syntax.h\"\n\n", cfile);
init();
fputs("/* syntax table used when not in quotes */\n", cfile);
add("\n", "CNL");
add("\\", "CBACK");
add("'", "CSQUOTE");
add("\"", "CDQUOTE");
add("`", "CBQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
add("<>();&| \t", "CSPCL");
print("basesyntax");
init();
fputs("\n/* syntax table used when in double quotes */\n", cfile);
add("\n", "CNL");
add("\\", "CBACK");
add("\"", "CENDQUOTE");
add("`", "CBQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
print("dqsyntax");
init();
fputs("\n/* syntax table used when in single quotes */\n", cfile);
add("\n", "CNL");
add("'", "CENDQUOTE");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
print("sqsyntax");
init();
fputs("\n/* syntax table used when in arithmetic */\n", cfile);
add("\n", "CNL");
add("\\", "CBACK");
add("`", "CBQUOTE");
add("'", "CSQUOTE");
add("\"", "CDQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
add("(", "CLP");
add(")", "CRP");
print("arisyntax");
filltable("0");
fputs("\n/* character classification table */\n", cfile);
add("0123456789", "ISDIGIT");
add("abcdefghijklmnopqrstucvwxyz", "ISLOWER");
add("ABCDEFGHIJKLMNOPQRSTUCVWXYZ", "ISUPPER");
add("_", "ISUNDER");
add("#?$!-*@", "ISSPECL");
print("is_type");
if (! digit_contig)
digit_convert();
exit(0);
}
/*
* Clear the syntax table.
*/
static void
filltable(dftval)
char *dftval;
{
int i;
for (i = 0 ; i < size ; i++)
syntax[i] = dftval;
}
/*
* Initialize the syntax table with default values.
*/
static void
init()
{
filltable("CWORD");
syntax[0] = "CEOF";
syntax[base + CTLESC] = "CCTL";
syntax[base + CTLVAR] = "CCTL";
syntax[base + CTLENDVAR] = "CCTL";
syntax[base + CTLBACKQ] = "CCTL";
syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
syntax[base + CTLARI] = "CCTL";
syntax[base + CTLENDARI] = "CCTL";
}
/*
* Add entries to the syntax table.
*/
static void
add(p, type)
char *p, *type;
{
while (*p)
syntax[*p++ + base] = type;
}
/*
* Output the syntax table.
*/
static void
print(name)
char *name;
{
int i;
int col;
fprintf(hfile, "extern const char %s[];\n", name);
fprintf(cfile, "const char %s[%d] = {\n", name, size);
col = 0;
for (i = 0 ; i < size ; i++) {
if (i == 0) {
fputs(" ", cfile);
} else if ((i & 03) == 0) {
fputs(",\n ", cfile);
col = 0;
} else {
putc(',', cfile);
while (++col < 9 * (i & 03))
putc(' ', cfile);
}
fputs(syntax[i], cfile);
col += strlen(syntax[i]);
}
fputs("\n};\n", cfile);
}
/*
* Output character classification macros (e.g. is_digit). If digits are
* contiguous, we can test for them quickly.
*/
static char *macro[] = {
"#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)",
"#define is_alpha(c)\t((c) != UPEOF && ((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))",
"#define is_name(c)\t((c) != UPEOF && ((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))",
"#define is_in_name(c)\t((c) != UPEOF && ((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))",
"#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))",
NULL
};
static void
output_type_macros()
{
char **pp;
if (digit_contig)
macro[0] = "#define is_digit(c)\t((unsigned)((c) - '0') <= 9)";
for (pp = macro ; *pp ; pp++)
fprintf(hfile, "%s\n", *pp);
if (digit_contig)
fputs("#define digit_val(c)\t((c) - '0')\n", hfile);
else
fputs("#define digit_val(c)\t(digit_value[c])\n", hfile);
}
/*
* Output digit conversion table (if digits are not contiguous).
*/
static void
digit_convert()
{
int maxdigit;
static char digit[] = "0123456789";
char *p;
int i;
maxdigit = 0;
for (p = digit ; *p ; p++)
if (*p > maxdigit)
maxdigit = *p;
fputs("extern const char digit_value[];\n", hfile);
fputs("\n\nconst char digit_value[] = {\n", cfile);
for (i = 0 ; i <= maxdigit ; i++) {
for (p = digit ; *p && *p != i ; p++);
if (*p == '\0')
p = digit;
fprintf(cfile, " %d,\n", p - digit);
}
fputs("};\n", cfile);
}

View File

@ -1,95 +0,0 @@
#!/bin/sh -
# $NetBSD: mktokens,v 1.8 1996/10/16 14:47:49 christos Exp $
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mktokens 8.1 (Berkeley) 5/31/93
# The following is a list of tokens. The second column is nonzero if the
# token marks the end of a list. The third column is the name to print in
# error messages.
cat > /tmp/ka$$ <<\!
TEOF 1 end of file
TNL 0 newline
TSEMI 0 ";"
TBACKGND 0 "&"
TAND 0 "&&"
TOR 0 "||"
TPIPE 0 "|"
TLP 0 "("
TRP 1 ")"
TENDCASE 1 ";;"
TENDBQUOTE 1 "`"
TREDIR 0 redirection
TWORD 0 word
TIF 0 "if"
TTHEN 1 "then"
TELSE 1 "else"
TELIF 1 "elif"
TFI 1 "fi"
TWHILE 0 "while"
TUNTIL 0 "until"
TFOR 0 "for"
TDO 1 "do"
TDONE 1 "done"
TBEGIN 0 "{"
TEND 1 "}"
TCASE 0 "case"
TESAC 1 "esac"
TNOT 0 "!"
!
nl=`wc -l /tmp/ka$$`
exec > token.h
awk '{print "#define " $1 " " NR-1}' /tmp/ka$$
echo '
/* Array indicating which tokens mark the end of a list */
const char tokendlist[] = {'
awk '{print "\t" $2 ","}' /tmp/ka$$
echo '};
char *const tokname[] = {'
sed -e 's/"/\\"/g' \
-e 's/[^ ]*[ ][ ]*[^ ]*[ ][ ]*\(.*\)/ "\1",/' \
/tmp/ka$$
echo '};
'
sed 's/"//g' /tmp/ka$$ | awk '
/TIF/{print "#define KWDOFFSET " NR-1; print ""; print "char *const parsekwd[] = {"}
/TIF/,/neverfound/{print " \"" $3 "\","}'
echo ' 0
};'
rm /tmp/ka$$

View File

@ -1,50 +0,0 @@
/* $NetBSD: myhistedit.h,v 1.6 1997/04/11 22:45:40 christos Exp $ */
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)myhistedit.h 8.2 (Berkeley) 5/4/95
*/
#include <histedit.h>
extern History *hist;
extern EditLine *el;
extern int displayhist;
void histedit __P((void));
void sethistsize __P((const char *));
void setterm __P((const char *));
int histcmd __P((int, char **));
int not_fcnumber __P((char *));
int str_to_event __P((char *, int));

View File

@ -1,144 +0,0 @@
/* $NetBSD: mystring.c,v 1.13 1997/07/04 21:02:15 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: mystring.c,v 1.13 1997/07/04 21:02:15 christos Exp $");
#endif
#endif /* not lint */
/*
* String functions.
*
* equal(s1, s2) Return true if strings are equal.
* scopy(from, to) Copy a string.
* scopyn(from, to, n) Like scopy, but checks for overflow.
* number(s) Convert a string of digits to an integer.
* is_number(s) Return true if s is a string of digits.
*/
#include <stdlib.h>
#include "shell.h"
#include "syntax.h"
#include "error.h"
#include "mystring.h"
char nullstr[1]; /* zero length string */
/*
* equal - #defined in mystring.h
*/
/*
* scopy - #defined in mystring.h
*/
/*
* scopyn - copy a string from "from" to "to", truncating the string
* if necessary. "To" is always nul terminated, even if
* truncation is performed. "Size" is the size of "to".
*/
void
scopyn(from, to, size)
char const *from;
char *to;
int size;
{
while (--size > 0) {
if ((*to++ = *from++) == '\0')
return;
}
*to = '\0';
}
/*
* prefix -- see if pfx is a prefix of string.
*/
int
prefix(pfx, string)
char const *pfx;
char const *string;
{
while (*pfx) {
if (*pfx++ != *string++)
return 0;
}
return 1;
}
/*
* Convert a string of digits to an integer, printing an error message on
* failure.
*/
int
number(s)
const char *s;
{
if (! is_number(s))
error("Illegal number: %s", (char *)s);
return atoi(s);
}
/*
* Check for a valid number. This should be elsewhere.
*/
int
is_number(p)
const char *p;
{
do {
if (! is_digit(*p))
return 0;
} while (*++p != '\0');
return 1;
}

View File

@ -1,49 +0,0 @@
/* $NetBSD: mystring.h,v 1.9 1995/05/11 21:29:42 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mystring.h 8.2 (Berkeley) 5/4/95
*/
#include <string.h>
void scopyn __P((const char *, char *, int));
int prefix __P((const char *, const char *));
int number __P((const char *));
int is_number __P((const char *));
#define equal(s1, s2) (strcmp(s1, s2) == 0)
#define scopy(s1, s2) ((void)strcpy(s2, s1))

View File

@ -1,169 +0,0 @@
/* $NetBSD: nodes.c.pat,v 1.8 1997/04/11 23:03:09 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95
*/
#include <stdlib.h>
/*
* Routine for dealing with parsed shell commands.
*/
#include "shell.h"
#include "nodes.h"
#include "memalloc.h"
#include "machdep.h"
#include "mystring.h"
int funcblocksize; /* size of structures in function */
int funcstringsize; /* size of strings in node */
pointer funcblock; /* block to allocate function from */
char *funcstring; /* block to allocate strings from */
%SIZES
STATIC void calcsize __P((union node *));
STATIC void sizenodelist __P((struct nodelist *));
STATIC union node *copynode __P((union node *));
STATIC struct nodelist *copynodelist __P((struct nodelist *));
STATIC char *nodesavestr __P((char *));
/*
* Make a copy of a parse tree.
*/
union node *
copyfunc(n)
union node *n;
{
if (n == NULL)
return NULL;
funcblocksize = 0;
funcstringsize = 0;
calcsize(n);
funcblock = ckmalloc(funcblocksize + funcstringsize);
funcstring = (char *) funcblock + funcblocksize;
return copynode(n);
}
STATIC void
calcsize(n)
union node *n;
{
%CALCSIZE
}
STATIC void
sizenodelist(lp)
struct nodelist *lp;
{
while (lp) {
funcblocksize += ALIGN(sizeof(struct nodelist));
calcsize(lp->n);
lp = lp->next;
}
}
STATIC union node *
copynode(n)
union node *n;
{
union node *new;
%COPY
return new;
}
STATIC struct nodelist *
copynodelist(lp)
struct nodelist *lp;
{
struct nodelist *start;
struct nodelist **lpp;
lpp = &start;
while (lp) {
*lpp = funcblock;
funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist));
(*lpp)->n = copynode(lp->n);
lp = lp->next;
lpp = &(*lpp)->next;
}
*lpp = NULL;
return start;
}
STATIC char *
nodesavestr(s)
char *s;
{
register char *p = s;
register char *q = funcstring;
char *rtn = funcstring;
while ((*q++ = *p++) != '\0')
continue;
funcstring = q;
return rtn;
}
/*
* Free a parse tree.
*/
void
freefunc(n)
union node *n;
{
if (n)
ckfree(n);
}

View File

@ -1,145 +0,0 @@
# $NetBSD: nodetypes,v 1.8 1995/05/11 21:29:44 christos Exp $
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)nodetypes 8.2 (Berkeley) 5/4/95
# This file describes the nodes used in parse trees. Unindented lines
# contain a node type followed by a structure tag. Subsequent indented
# lines specify the fields of the structure. Several node types can share
# the same structure, in which case the fields of the structure should be
# specified only once.
#
# A field of a structure is described by the name of the field followed
# by a type. The currently implemented types are:
# nodeptr - a pointer to a node
# nodelist - a pointer to a list of nodes
# string - a pointer to a nul terminated string
# int - an integer
# other - any type that can be copied by assignment
# temp - a field that doesn't have to be copied when the node is copied
# The last two types should be followed by the text of a C declaration for
# the field.
NSEMI nbinary # two commands separated by a semicolon
type int
ch1 nodeptr # the first child
ch2 nodeptr # the second child
NCMD ncmd # a simple command
type int
backgnd int # set to run command in background
args nodeptr # the arguments
redirect nodeptr # list of file redirections
NPIPE npipe # a pipeline
type int
backgnd int # set to run pipeline in background
cmdlist nodelist # the commands in the pipeline
NREDIR nredir # redirection (of a compex command)
type int
n nodeptr # the command
redirect nodeptr # list of file redirections
NBACKGND nredir # run command in background
NSUBSHELL nredir # run command in a subshell
NAND nbinary # the && operator
NOR nbinary # the || operator
NIF nif # the if statement. Elif clauses are handled
type int # using multiple if nodes.
test nodeptr # if test
ifpart nodeptr # then ifpart
elsepart nodeptr # else elsepart
NWHILE nbinary # the while statement. First child is the test
NUNTIL nbinary # the until statement
NFOR nfor # the for statement
type int
args nodeptr # for var in args
body nodeptr # do body; done
var string # the for variable
NCASE ncase # a case statement
type int
expr nodeptr # the word to switch on
cases nodeptr # the list of cases (NCLIST nodes)
NCLIST nclist # a case
type int
next nodeptr # the next case in list
pattern nodeptr # list of patterns for this case
body nodeptr # code to execute for this case
NDEFUN narg # define a function. The "next" field contains
# the body of the function.
NARG narg # represents a word
type int
next nodeptr # next word in list
text string # the text of the word
backquote nodelist # list of commands in back quotes
NTO nfile # fd> fname
NFROM nfile # fd< fname
NAPPEND nfile # fd>> fname
type int
next nodeptr # next redirection in list
fd int # file descriptor being redirected
fname nodeptr # file name, in a NARG node
expfname temp char *expfname # actual file name
NTOFD ndup # fd<&dupfd
NFROMFD ndup # fd>&dupfd
type int
next nodeptr # next redirection in list
fd int # file descriptor being redirected
dupfd int # file descriptor to duplicate
vname nodeptr # file name if fd>&$var
NHERE nhere # fd<<\!
NXHERE nhere # fd<<!
type int
next nodeptr # next redirection in list
fd int # file descriptor being redirected
doc nodeptr # input to command (NARG node)
NNOT nnot # ! command (actually pipeline)
type int
com nodeptr

View File

@ -1,541 +0,0 @@
/* $NetBSD: options.c,v 1.25 1997/07/04 21:02:16 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: options.c,v 1.25 1997/07/04 21:02:16 christos Exp $");
#endif
#endif /* not lint */
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#define DEFINE_OPTIONS
#include "options.h"
#undef DEFINE_OPTIONS
#include "nodes.h" /* for other header files */
#include "eval.h"
#include "jobs.h"
#include "input.h"
#include "output.h"
#include "trap.h"
#include "var.h"
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#ifndef SMALL
#include "myhistedit.h"
#endif
char *arg0; /* value of $0 */
struct shparam shellparam; /* current positional parameters */
char **argptr; /* argument list for builtin commands */
char *optarg; /* set by nextopt (like getopt) */
char *optptr; /* used by nextopt */
char *minusc; /* argument to -c option */
STATIC void options __P((int));
STATIC void minus_o __P((char *, int));
STATIC void setoption __P((int, int));
STATIC int getopts __P((char *, char *, char **, char ***, char **));
/*
* Process the shell command line arguments.
*/
void
procargs(argc, argv)
int argc;
char **argv;
{
int i;
argptr = argv;
if (argc > 0)
argptr++;
for (i = 0; i < NOPTS; i++)
optlist[i].val = 2;
options(1);
if (*argptr == NULL && minusc == NULL)
sflag = 1;
if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1))
iflag = 1;
if (mflag == 2)
mflag = iflag;
for (i = 0; i < NOPTS; i++)
if (optlist[i].val == 2)
optlist[i].val = 0;
arg0 = argv[0];
if (sflag == 0 && minusc == NULL) {
commandname = arg0 = *argptr++;
setinputfile(commandname, 0);
}
/* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
if (argptr && minusc && *argptr)
arg0 = *argptr++;
shellparam.p = argptr;
shellparam.reset = 1;
/* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
while (*argptr) {
shellparam.nparam++;
argptr++;
}
optschanged();
}
void
optschanged()
{
setinteractive(iflag);
#ifndef SMALL
histedit();
#endif
setjobctl(mflag);
}
/*
* Process shell options. The global variable argptr contains a pointer
* to the argument list; we advance it past the options.
*/
STATIC void
options(cmdline)
int cmdline;
{
char *p;
int val;
int c;
if (cmdline)
minusc = NULL;
while ((p = *argptr) != NULL) {
argptr++;
if ((c = *p++) == '-') {
val = 1;
if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
if (!cmdline) {
/* "-" means turn off -x and -v */
if (p[0] == '\0')
xflag = vflag = 0;
/* "--" means reset params */
else if (*argptr == NULL)
setparam(argptr);
}
break; /* "-" or "--" terminates options */
}
} else if (c == '+') {
val = 0;
} else {
argptr--;
break;
}
while ((c = *p++) != '\0') {
if (c == 'c' && cmdline) {
char *q;
#ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */
if (*p == '\0')
#endif
q = *argptr++;
if (q == NULL || minusc != NULL)
error("Bad -c option");
minusc = q;
#ifdef NOHACK
break;
#endif
} else if (c == 'o') {
minus_o(*argptr, val);
if (*argptr)
argptr++;
} else {
setoption(c, val);
}
}
}
}
STATIC void
minus_o(name, val)
char *name;
int val;
{
int i;
if (name == NULL) {
out1str("Current option settings\n");
for (i = 0; i < NOPTS; i++)
out1fmt("%-16s%s\n", optlist[i].name,
optlist[i].val ? "on" : "off");
} else {
for (i = 0; i < NOPTS; i++)
if (equal(name, optlist[i].name)) {
setoption(optlist[i].letter, val);
return;
}
error("Illegal option -o %s", name);
}
}
STATIC void
setoption(flag, val)
char flag;
int val;
{
int i;
for (i = 0; i < NOPTS; i++)
if (optlist[i].letter == flag) {
optlist[i].val = val;
if (val) {
/* #%$ hack for ksh semantics */
if (flag == 'V')
Eflag = 0;
else if (flag == 'E')
Vflag = 0;
}
return;
}
error("Illegal option -%c", flag);
}
#ifdef mkinit
INCLUDE "options.h"
SHELLPROC {
int i;
for (i = 0; i < NOPTS; i++)
optlist[i].val = 0;
optschanged();
}
#endif
/*
* Set the shell parameters.
*/
void
setparam(argv)
char **argv;
{
char **newparam;
char **ap;
int nparam;
for (nparam = 0 ; argv[nparam] ; nparam++);
ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
while (*argv) {
*ap++ = savestr(*argv++);
}
*ap = NULL;
freeparam(&shellparam);
shellparam.malloc = 1;
shellparam.nparam = nparam;
shellparam.p = newparam;
shellparam.optnext = NULL;
}
/*
* Free the list of positional parameters.
*/
void
freeparam(param)
struct shparam *param;
{
char **ap;
if (param->malloc) {
for (ap = param->p ; *ap ; ap++)
ckfree(*ap);
ckfree(param->p);
}
}
/*
* The shift builtin command.
*/
int
shiftcmd(argc, argv)
int argc;
char **argv;
{
int n;
char **ap1, **ap2;
n = 1;
if (argc > 1)
n = number(argv[1]);
if (n > shellparam.nparam)
error("can't shift that many");
INTOFF;
shellparam.nparam -= n;
for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
if (shellparam.malloc)
ckfree(*ap1);
}
ap2 = shellparam.p;
while ((*ap2++ = *ap1++) != NULL);
shellparam.optnext = NULL;
INTON;
return 0;
}
/*
* The set command builtin.
*/
int
setcmd(argc, argv)
int argc;
char **argv;
{
if (argc == 1)
return showvarscmd(argc, argv);
INTOFF;
options(0);
optschanged();
if (*argptr != NULL) {
setparam(argptr);
}
INTON;
return 0;
}
void
getoptsreset(value)
const char *value;
{
if (number(value) == 1) {
shellparam.optnext = NULL;
shellparam.reset = 1;
}
}
/*
* The getopts builtin. Shellparam.optnext points to the next argument
* to be processed. Shellparam.optptr points to the next character to
* be processed in the current argument. If shellparam.optnext is NULL,
* then it's the first time getopts has been called.
*/
int
getoptscmd(argc, argv)
int argc;
char **argv;
{
char **optbase;
if (argc < 3)
error("Usage: getopts optstring var [arg]");
else if (argc == 3)
optbase = shellparam.p;
else
optbase = &argv[3];
if (shellparam.reset == 1) {
shellparam.optnext = optbase;
shellparam.optptr = NULL;
shellparam.reset = 0;
}
return getopts(argv[1], argv[2], optbase, &shellparam.optnext,
&shellparam.optptr);
}
STATIC int
getopts(optstr, optvar, optfirst, optnext, optptr)
char *optstr;
char *optvar;
char **optfirst;
char ***optnext;
char **optptr;
{
char *p, *q;
char c = '?';
int done = 0;
int ind = 0;
int err = 0;
char s[10];
if ((p = *optptr) == NULL || *p == '\0') {
/* Current word is done, advance */
if (*optnext == NULL)
return 1;
p = **optnext;
if (p == NULL || *p != '-' || *++p == '\0') {
atend:
ind = *optnext - optfirst + 1;
*optnext = NULL;
p = NULL;
done = 1;
goto out;
}
(*optnext)++;
if (p[0] == '-' && p[1] == '\0') /* check for "--" */
goto atend;
}
c = *p++;
for (q = optstr; *q != c; ) {
if (*q == '\0') {
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
err |= setvarsafe("OPTARG", s, 0);
}
else {
out1fmt("Illegal option -%c\n", c);
(void) unsetvar("OPTARG");
}
c = '?';
goto bad;
}
if (*++q == ':')
q++;
}
if (*++q == ':') {
if (*p == '\0' && (p = **optnext) == NULL) {
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
err |= setvarsafe("OPTARG", s, 0);
c = ':';
}
else {
out1fmt("No arg for -%c option\n", c);
(void) unsetvar("OPTARG");
c = '?';
}
goto bad;
}
if (p == **optnext)
(*optnext)++;
setvarsafe("OPTARG", p, 0);
p = NULL;
}
else
setvarsafe("OPTARG", "", 0);
ind = *optnext - optfirst + 1;
goto out;
bad:
ind = 1;
*optnext = NULL;
p = NULL;
out:
*optptr = p;
fmtstr(s, sizeof(s), "%d", ind);
err |= setvarsafe("OPTIND", s, VNOFUNC);
s[0] = c;
s[1] = '\0';
err |= setvarsafe(optvar, s, 0);
if (err) {
*optnext = NULL;
*optptr = NULL;
flushall();
exraise(EXERROR);
}
return done;
}
/*
* XXX - should get rid of. have all builtins use getopt(3). the
* library getopt must have the BSD extension static variable "optreset"
* otherwise it can't be used within the shell safely.
*
* Standard option processing (a la getopt) for builtin routines. The
* only argument that is passed to nextopt is the option string; the
* other arguments are unnecessary. It return the character, or '\0' on
* end of input.
*/
int
nextopt(optstring)
char *optstring;
{
char *p, *q;
char c;
if ((p = optptr) == NULL || *p == '\0') {
p = *argptr;
if (p == NULL || *p != '-' || *++p == '\0')
return '\0';
argptr++;
if (p[0] == '-' && p[1] == '\0') /* check for "--" */
return '\0';
}
c = *p++;
for (q = optstring ; *q != c ; ) {
if (*q == '\0')
error("Illegal option -%c", c);
if (*++q == ':')
q++;
}
if (*++q == ':') {
if (*p == '\0' && (p = *argptr++) == NULL)
error("No arg for -%c option", c);
optarg = p;
p = NULL;
}
optptr = p;
return c;
}

View File

@ -1,114 +0,0 @@
/* $NetBSD: options.h,v 1.11 1996/11/06 01:17:12 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)options.h 8.2 (Berkeley) 5/4/95
*/
struct shparam {
int nparam; /* # of positional parameters (without $0) */
unsigned char malloc; /* if parameter list dynamically allocated */
unsigned char reset; /* if getopts has been reset */
char **p; /* parameter list */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
};
#define eflag optlist[0].val
#define fflag optlist[1].val
#define Iflag optlist[2].val
#define iflag optlist[3].val
#define mflag optlist[4].val
#define nflag optlist[5].val
#define sflag optlist[6].val
#define xflag optlist[7].val
#define vflag optlist[8].val
#define Vflag optlist[9].val
#define Eflag optlist[10].val
#define Cflag optlist[11].val
#define aflag optlist[12].val
#define bflag optlist[13].val
#define uflag optlist[14].val
#define NOPTS 15
struct optent {
const char *name;
const char letter;
char val;
};
#ifdef DEFINE_OPTIONS
struct optent optlist[NOPTS] = {
{ "errexit", 'e', 0 },
{ "noglob", 'f', 0 },
{ "ignoreeof", 'I', 0 },
{ "interactive",'i', 0 },
{ "monitor", 'm', 0 },
{ "noexec", 'n', 0 },
{ "stdin", 's', 0 },
{ "xtrace", 'x', 0 },
{ "verbose", 'v', 0 },
{ "vi", 'V', 0 },
{ "emacs", 'E', 0 },
{ "noclobber", 'C', 0 },
{ "allexport", 'a', 0 },
{ "notify", 'b', 0 },
{ "nounset", 'u', 0 },
};
#else
extern struct optent optlist[NOPTS];
#endif
extern char *minusc; /* argument to -c option */
extern char *arg0; /* $0 */
extern struct shparam shellparam; /* $@ */
extern char **argptr; /* argument list for builtin commands */
extern char *optarg; /* set by nextopt */
extern char *optptr; /* used by nextopt */
void procargs __P((int, char **));
void optschanged __P((void));
void setparam __P((char **));
void freeparam __P((struct shparam *));
int shiftcmd __P((int, char **));
int setcmd __P((int, char **));
int getoptscmd __P((int, char **));
int nextopt __P((char *));
void getoptsreset __P((const char *));

View File

@ -1,584 +0,0 @@
/* $NetBSD: output.c,v 1.19 1997/07/04 21:02:18 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: output.c,v 1.19 1997/07/04 21:02:18 christos Exp $");
#endif
#endif /* not lint */
/*
* Shell output routines. We use our own output routines because:
* When a builtin command is interrupted we have to discard
* any pending output.
* When a builtin command appears in back quotes, we want to
* save the output of the command in a region obtained
* via malloc, rather than doing a fork and reading the
* output of the command via a pipe.
* Our output routines may be smaller than the stdio routines.
*/
#include <sys/types.h> /* quad_t */
#include <sys/ioctl.h>
#include <stdio.h> /* defines BUFSIZ */
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#include "syntax.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#define OUTBUFSIZ BUFSIZ
#define BLOCK_OUT -2 /* output to a fixed block of memory */
#define MEM_OUT -3 /* output to dynamically allocated memory */
#define OUTPUT_ERR 01 /* error occurred on output */
struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};
struct output errout = {NULL, 0, NULL, 100, 2, 0};
struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};
struct output *out1 = &output;
struct output *out2 = &errout;
#ifdef mkinit
INCLUDE "output.h"
INCLUDE "memalloc.h"
RESET {
out1 = &output;
out2 = &errout;
if (memout.buf != NULL) {
ckfree(memout.buf);
memout.buf = NULL;
}
}
#endif
#ifdef notdef /* no longer used */
/*
* Set up an output file to write to memory rather than a file.
*/
void
open_mem(block, length, file)
char *block;
int length;
struct output *file;
{
file->nextc = block;
file->nleft = --length;
file->fd = BLOCK_OUT;
file->flags = 0;
}
#endif
void
out1str(p)
const char *p;
{
outstr(p, out1);
}
void
out2str(p)
const char *p;
{
outstr(p, out2);
}
void
outstr(p, file)
const char *p;
struct output *file;
{
while (*p)
outc(*p++, file);
if (file == out2)
flushout(file);
}
char out_junk[16];
void
emptyoutbuf(dest)
struct output *dest;
{
int offset;
if (dest->fd == BLOCK_OUT) {
dest->nextc = out_junk;
dest->nleft = sizeof out_junk;
dest->flags |= OUTPUT_ERR;
} else if (dest->buf == NULL) {
INTOFF;
dest->buf = ckmalloc(dest->bufsize);
dest->nextc = dest->buf;
dest->nleft = dest->bufsize;
INTON;
} else if (dest->fd == MEM_OUT) {
offset = dest->bufsize;
INTOFF;
dest->bufsize <<= 1;
dest->buf = ckrealloc(dest->buf, dest->bufsize);
dest->nleft = dest->bufsize - offset;
dest->nextc = dest->buf + offset;
INTON;
} else {
flushout(dest);
}
dest->nleft--;
}
void
flushall() {
flushout(&output);
flushout(&errout);
}
void
flushout(dest)
struct output *dest;
{
if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0)
return;
if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0)
dest->flags |= OUTPUT_ERR;
dest->nextc = dest->buf;
dest->nleft = dest->bufsize;
}
void
freestdout() {
INTOFF;
if (output.buf) {
ckfree(output.buf);
output.buf = NULL;
output.nleft = 0;
}
INTON;
}
#ifdef __STDC__
void
outfmt(struct output *file, char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
doformat(file, fmt, ap);
va_end(ap);
}
void
out1fmt(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
doformat(out1, fmt, ap);
va_end(ap);
}
void
dprintf(char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
doformat(out2, fmt, ap);
va_end(ap);
flushout(out2);
}
void
fmtstr(char *outbuf, int length, char *fmt, ...) {
va_list ap;
struct output strout;
va_start(ap, fmt);
strout.nextc = outbuf;
strout.nleft = length;
strout.fd = BLOCK_OUT;
strout.flags = 0;
doformat(&strout, fmt, ap);
outc('\0', &strout);
if (strout.flags & OUTPUT_ERR)
outbuf[length - 1] = '\0';
}
#else /* not __STDC__ */
void
outfmt(va_alist)
va_dcl
{
va_list ap;
struct output *file;
char *fmt;
va_start(ap);
file = va_arg(ap, struct output *);
fmt = va_arg(ap, char *);
doformat(file, fmt, ap);
va_end(ap);
}
void
out1fmt(va_alist)
va_dcl
{
va_list ap;
char *fmt;
va_start(ap);
fmt = va_arg(ap, char *);
doformat(out1, fmt, ap);
va_end(ap);
}
void
dprintf(va_alist)
va_dcl
{
va_list ap;
char *fmt;
va_start(ap);
fmt = va_arg(ap, char *);
doformat(out2, fmt, ap);
va_end(ap);
flushout(out2);
}
void
fmtstr(va_alist)
va_dcl
{
va_list ap;
struct output strout;
char *outbuf;
int length;
char *fmt;
va_start(ap);
outbuf = va_arg(ap, char *);
length = va_arg(ap, int);
fmt = va_arg(ap, char *);
strout.nextc = outbuf;
strout.nleft = length;
strout.fd = BLOCK_OUT;
strout.flags = 0;
doformat(&strout, fmt, ap);
outc('\0', &strout);
if (strout.flags & OUTPUT_ERR)
outbuf[length - 1] = '\0';
}
#endif /* __STDC__ */
/*
* Formatted output. This routine handles a subset of the printf formats:
* - Formats supported: d, u, o, X, s, and c.
* - The x format is also accepted but is treated like X.
* - The l and q modifiers are accepted.
* - The - and # flags are accepted; # only works with the o format.
* - Width and precision may be specified with any format except c.
* - An * may be given for the width or precision.
* - The obsolete practice of preceding the width with a zero to get
* zero padding is not supported; use the precision field.
* - A % may be printed by writing %% in the format string.
*/
#define TEMPSIZE 24
static const char digit[] = "0123456789ABCDEF";
void
doformat(dest, f, ap)
struct output *dest;
char *f; /* format string */
va_list ap;
{
char c;
char temp[TEMPSIZE];
int flushleft;
int sharp;
int width;
int prec;
int islong;
int isquad;
char *p;
int sign;
#ifdef BSD4_4
quad_t l;
u_quad_t num;
#else
long l;
u_long num;
#endif
unsigned base;
int len;
int size;
int pad;
while ((c = *f++) != '\0') {
if (c != '%') {
outc(c, dest);
continue;
}
flushleft = 0;
sharp = 0;
width = 0;
prec = -1;
islong = 0;
isquad = 0;
for (;;) {
if (*f == '-')
flushleft++;
else if (*f == '#')
sharp++;
else
break;
f++;
}
if (*f == '*') {
width = va_arg(ap, int);
f++;
} else {
while (is_digit(*f)) {
width = 10 * width + digit_val(*f++);
}
}
if (*f == '.') {
if (*++f == '*') {
prec = va_arg(ap, int);
f++;
} else {
prec = 0;
while (is_digit(*f)) {
prec = 10 * prec + digit_val(*f++);
}
}
}
if (*f == 'l') {
islong++;
f++;
} else if (*f == 'q') {
isquad++;
f++;
}
switch (*f) {
case 'd':
#ifdef BSD4_4
if (isquad)
l = va_arg(ap, quad_t);
else
#endif
if (islong)
l = va_arg(ap, long);
else
l = va_arg(ap, int);
sign = 0;
num = l;
if (l < 0) {
num = -l;
sign = 1;
}
base = 10;
goto number;
case 'u':
base = 10;
goto uns_number;
case 'o':
base = 8;
goto uns_number;
case 'x':
/* we don't implement 'x'; treat like 'X' */
case 'X':
base = 16;
uns_number: /* an unsigned number */
sign = 0;
#ifdef BSD4_4
if (isquad)
num = va_arg(ap, u_quad_t);
else
#endif
if (islong)
num = va_arg(ap, unsigned long);
else
num = va_arg(ap, unsigned int);
number: /* process a number */
p = temp + TEMPSIZE - 1;
*p = '\0';
while (num) {
*--p = digit[num % base];
num /= base;
}
len = (temp + TEMPSIZE - 1) - p;
if (prec < 0)
prec = 1;
if (sharp && *f == 'o' && prec <= len)
prec = len + 1;
pad = 0;
if (width) {
size = len;
if (size < prec)
size = prec;
size += sign;
pad = width - size;
if (flushleft == 0) {
while (--pad >= 0)
outc(' ', dest);
}
}
if (sign)
outc('-', dest);
prec -= len;
while (--prec >= 0)
outc('0', dest);
while (*p)
outc(*p++, dest);
while (--pad >= 0)
outc(' ', dest);
break;
case 's':
p = va_arg(ap, char *);
pad = 0;
if (width) {
len = strlen(p);
if (prec >= 0 && len > prec)
len = prec;
pad = width - len;
if (flushleft == 0) {
while (--pad >= 0)
outc(' ', dest);
}
}
prec++;
while (--prec != 0 && *p)
outc(*p++, dest);
while (--pad >= 0)
outc(' ', dest);
break;
case 'c':
c = va_arg(ap, int);
outc(c, dest);
break;
default:
outc(*f, dest);
break;
}
f++;
}
}
/*
* Version of write which resumes after a signal is caught.
*/
int
xwrite(fd, buf, nbytes)
int fd;
char *buf;
int nbytes;
{
int ntry;
int i;
int n;
n = nbytes;
ntry = 0;
for (;;) {
i = write(fd, buf, n);
if (i > 0) {
if ((n -= i) <= 0)
return nbytes;
buf += i;
ntry = 0;
} else if (i == 0) {
if (++ntry > 10)
return nbytes - n;
} else if (errno != EINTR) {
return -1;
}
}
}
/*
* Version of ioctl that retries after a signal is caught.
* XXX unused function
*/
int
xioctl(fd, request, arg)
int fd;
unsigned long request;
char * arg;
{
int i;
while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);
return i;
}

View File

@ -1,85 +0,0 @@
/* $NetBSD: output.h,v 1.13 1997/04/11 23:08:40 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)output.h 8.2 (Berkeley) 5/4/95
*/
#ifndef OUTPUT_INCL
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
struct output {
char *nextc;
int nleft;
char *buf;
int bufsize;
short fd;
short flags;
};
extern struct output output;
extern struct output errout;
extern struct output memout;
extern struct output *out1;
extern struct output *out2;
void open_mem __P((char *, int, struct output *));
void out1str __P((const char *));
void out2str __P((const char *));
void outstr __P((const char *, struct output *));
void emptyoutbuf __P((struct output *));
void flushall __P((void));
void flushout __P((struct output *));
void freestdout __P((void));
void outfmt __P((struct output *, char *, ...));
void out1fmt __P((char *, ...));
void dprintf __P((char *, ...));
void fmtstr __P((char *, int, char *, ...));
void doformat __P((struct output *, char *, va_list));
int xwrite __P((int, char *, int));
int xioctl __P((int, unsigned long, char *));
#define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
#define out1c(c) outc(c, out1);
#define out2c(c) outc(c, out2);
#define OUTPUT_INCL
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +0,0 @@
/* $NetBSD: parser.h,v 1.11 1996/10/16 15:45:15 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)parser.h 8.3 (Berkeley) 5/4/95
*/
/* control characters in argument strings */
#define CTLESC '\201'
#define CTLVAR '\202'
#define CTLENDVAR '\203'
#define CTLBACKQ '\204'
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
/* CTLBACKQ | CTLQUOTE == '\205' */
#define CTLARI '\206'
#define CTLENDARI '\207'
/* variable substitution byte (follows CTLVAR) */
#define VSTYPE 0x0f /* type of variable substitution */
#define VSNUL 0x10 /* colon--treat the empty string as unset */
#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
/* values of VSTYPE field */
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */
#define VSMINUS 0x2 /* ${var-text} */
#define VSPLUS 0x3 /* ${var+text} */
#define VSQUESTION 0x4 /* ${var?message} */
#define VSASSIGN 0x5 /* ${var=text} */
#define VSTRIMLEFT 0x6 /* ${var#pattern} */
#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
#define VSLENGTH 0xa /* ${#var} */
/*
* NEOF is returned by parsecmd when it encounters an end of file. It
* must be distinct from NULL, so we use the address of a variable that
* happens to be handy.
*/
extern int tokpushback;
#define NEOF ((union node *)&tokpushback)
extern int whichprompt; /* 1 == PS1, 2 == PS2 */
union node *parsecmd __P((int));
void fixredir __P((union node *, const char *, int));
int goodname __P((char *));
char *getprompt __P((void *));

View File

@ -1,375 +0,0 @@
/* $NetBSD: redir.c,v 1.16 1997/07/04 21:02:21 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: redir.c,v 1.16 1997/07/04 21:02:21 christos Exp $");
#endif
#endif /* not lint */
#include <sys/types.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
/*
* Code for dealing with input/output redirection.
*/
#include "shell.h"
#include "nodes.h"
#include "jobs.h"
#include "expand.h"
#include "redir.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#define EMPTY -2 /* marks an unused slot in redirtab */
#define PIPESIZE 4096 /* amount of buffering in a pipe */
MKINIT
struct redirtab {
struct redirtab *next;
short renamed[10];
};
MKINIT struct redirtab *redirlist;
/*
* We keep track of whether or not fd0 has been redirected. This is for
* background commands, where we want to redirect fd0 to /dev/null only
* if it hasn't already been redirected.
*/
int fd0_redirected = 0;
STATIC void openredirect __P((union node *, char[10 ]));
STATIC int openhere __P((union node *));
/*
* Process a list of redirection commands. If the REDIR_PUSH flag is set,
* old file descriptors are stashed away so that the redirection can be
* undone by calling popredir. If the REDIR_BACKQ flag is set, then the
* standard output, and the standard error if it becomes a duplicate of
* stdout, is saved in memory.
*/
void
redirect(redir, flags)
union node *redir;
int flags;
{
union node *n;
struct redirtab *sv = NULL;
int i;
int fd;
int try;
char memory[10]; /* file descriptors to write to memory */
for (i = 10 ; --i >= 0 ; )
memory[i] = 0;
memory[1] = flags & REDIR_BACKQ;
if (flags & REDIR_PUSH) {
sv = ckmalloc(sizeof (struct redirtab));
for (i = 0 ; i < 10 ; i++)
sv->renamed[i] = EMPTY;
sv->next = redirlist;
redirlist = sv;
}
for (n = redir ; n ; n = n->nfile.next) {
fd = n->nfile.fd;
try = 0;
if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
n->ndup.dupfd == fd)
continue; /* redirect from/to same file descriptor */
if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
INTOFF;
again:
if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
switch (errno) {
case EBADF:
if (!try) {
openredirect(n, memory);
try++;
goto again;
}
/* FALLTHROUGH*/
default:
INTON;
error("%d: %s", fd, strerror(errno));
break;
}
}
if (!try) {
sv->renamed[fd] = i;
close(fd);
}
INTON;
} else {
close(fd);
}
if (fd == 0)
fd0_redirected++;
if (!try)
openredirect(n, memory);
}
if (memory[1])
out1 = &memout;
if (memory[2])
out2 = &memout;
}
STATIC void
openredirect(redir, memory)
union node *redir;
char memory[10];
{
int fd = redir->nfile.fd;
char *fname;
int f;
/*
* We suppress interrupts so that we won't leave open file
* descriptors around. This may not be such a good idea because
* an open of a device or a fifo can block indefinitely.
*/
INTOFF;
memory[fd] = 0;
switch (redir->nfile.type) {
case NFROM:
fname = redir->nfile.expfname;
if ((f = open(fname, O_RDONLY)) < 0)
error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
movefd:
if (f != fd) {
copyfd(f, fd);
close(f);
}
break;
case NTO:
fname = redir->nfile.expfname;
#ifdef O_CREAT
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#else
if ((f = creat(fname, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#endif
goto movefd;
case NAPPEND:
fname = redir->nfile.expfname;
#ifdef O_APPEND
if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#else
if ((f = open(fname, O_WRONLY)) < 0
&& (f = creat(fname, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
lseek(f, (off_t)0, 2);
#endif
goto movefd;
case NTOFD:
case NFROMFD:
if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
if (memory[redir->ndup.dupfd])
memory[fd] = 1;
else
copyfd(redir->ndup.dupfd, fd);
}
break;
case NHERE:
case NXHERE:
f = openhere(redir);
goto movefd;
default:
abort();
}
INTON;
}
/*
* Handle here documents. Normally we fork off a process to write the
* data to a pipe. If the document is short, we can stuff the data in
* the pipe without forking.
*/
STATIC int
openhere(redir)
union node *redir;
{
int pip[2];
int len = 0;
if (pipe(pip) < 0)
error("Pipe call failed");
if (redir->type == NHERE) {
len = strlen(redir->nhere.doc->narg.text);
if (len <= PIPESIZE) {
xwrite(pip[1], redir->nhere.doc->narg.text, len);
goto out;
}
}
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
close(pip[0]);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
signal(SIGPIPE, SIG_DFL);
if (redir->type == NHERE)
xwrite(pip[1], redir->nhere.doc->narg.text, len);
else
expandhere(redir->nhere.doc, pip[1]);
_exit(0);
}
out:
close(pip[1]);
return pip[0];
}
/*
* Undo the effects of the last redirection.
*/
void
popredir() {
struct redirtab *rp = redirlist;
int i;
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] != EMPTY) {
if (i == 0)
fd0_redirected--;
close(i);
if (rp->renamed[i] >= 0) {
copyfd(rp->renamed[i], i);
close(rp->renamed[i]);
}
}
}
INTOFF;
redirlist = rp->next;
ckfree(rp);
INTON;
}
/*
* Undo all redirections. Called on error or interrupt.
*/
#ifdef mkinit
INCLUDE "redir.h"
RESET {
while (redirlist)
popredir();
}
SHELLPROC {
clearredir();
}
#endif
/* Return true if fd 0 has already been redirected at least once. */
int
fd0_redirected_p () {
return fd0_redirected != 0;
}
/*
* Discard all saved file descriptors.
*/
void
clearredir() {
struct redirtab *rp;
int i;
for (rp = redirlist ; rp ; rp = rp->next) {
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] >= 0) {
close(rp->renamed[i]);
}
rp->renamed[i] = EMPTY;
}
}
}
/*
* Copy a file descriptor to be >= to. Returns -1
* if the source file descriptor is closed, EMPTY if there are no unused
* file descriptors left.
*/
int
copyfd(from, to)
int from;
int to;
{
int newfd;
newfd = fcntl(from, F_DUPFD, to);
if (newfd < 0) {
if (errno == EMFILE)
return EMPTY;
else
error("%d: %s", from, strerror(errno));
}
return newfd;
}

View File

@ -1,51 +0,0 @@
/* $NetBSD: redir.h,v 1.10 1996/10/16 15:45:18 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)redir.h 8.2 (Berkeley) 5/4/95
*/
/* flags passed to redirect */
#define REDIR_PUSH 01 /* save previous values of file descriptors */
#define REDIR_BACKQ 02 /* save the command output in memory */
union node;
void redirect __P((union node *, int));
void popredir __P((void));
int fd0_redirected_p __P((void));
void clearredir __P((void));
int copyfd __P((int, int));

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
/* $NetBSD: shell.h,v 1.10 1996/10/16 15:21:49 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)shell.h 8.2 (Berkeley) 5/4/95
*/
/*
* The follow should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
* SHORTNAMES -> 1 if your linker cannot handle long names.
* define BSD if you are running 4.2 BSD or later.
* define SYSV if you are running under System V.
* define DEBUG=1 to compile in debugging (set global "debug" to turn on)
* define DEBUG=2 to compile in and turn on debugging.
*
* When debugging is on, debugging info will be written to $HOME/trace and
* a quit signal will generate a core dump.
*/
#define JOBS 1
#ifndef BSD
#define BSD 1
#endif
#ifdef __STDC__
typedef void *pointer;
#ifndef NULL
#define NULL (void *)0
#endif
#else /* not __STDC__ */
typedef char *pointer;
#ifndef NULL
#define NULL 0
#endif
#endif /* not __STDC__ */
#define STATIC /* empty */
#define MKINIT /* empty */
#include <sys/cdefs.h>
extern char nullstr[1]; /* null string */
#ifdef DEBUG
#define TRACE(param) trace param
#else
#define TRACE(param)
#endif

View File

@ -1,446 +0,0 @@
/* $NetBSD: show.c,v 1.15 1997/07/04 21:02:22 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: show.c,v 1.15 1997/07/04 21:02:22 christos Exp $");
#endif
#endif /* not lint */
#include <stdio.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "shell.h"
#include "parser.h"
#include "nodes.h"
#include "mystring.h"
#include "show.h"
#ifdef DEBUG
static void shtree __P((union node *, int, char *, FILE*));
static void shcmd __P((union node *, FILE *));
static void sharg __P((union node *, FILE *));
static void indent __P((int, char *, FILE *));
static void trstring __P((char *));
void
showtree(n)
union node *n;
{
trputs("showtree called\n");
shtree(n, 1, NULL, stdout);
}
static void
shtree(n, ind, pfx, fp)
union node *n;
int ind;
char *pfx;
FILE *fp;
{
struct nodelist *lp;
char *s;
if (n == NULL)
return;
indent(ind, pfx, fp);
switch(n->type) {
case NSEMI:
s = "; ";
goto binop;
case NAND:
s = " && ";
goto binop;
case NOR:
s = " || ";
binop:
shtree(n->nbinary.ch1, ind, NULL, fp);
/* if (ind < 0) */
fputs(s, fp);
shtree(n->nbinary.ch2, ind, NULL, fp);
break;
case NCMD:
shcmd(n, fp);
if (ind >= 0)
putc('\n', fp);
break;
case NPIPE:
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
shcmd(lp->n, fp);
if (lp->next)
fputs(" | ", fp);
}
if (n->npipe.backgnd)
fputs(" &", fp);
if (ind >= 0)
putc('\n', fp);
break;
default:
fprintf(fp, "<node type %d>", n->type);
if (ind >= 0)
putc('\n', fp);
break;
}
}
static void
shcmd(cmd, fp)
union node *cmd;
FILE *fp;
{
union node *np;
int first;
char *s;
int dftfd;
first = 1;
for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
if (! first)
putchar(' ');
sharg(np, fp);
first = 0;
}
for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
if (! first)
putchar(' ');
switch (np->nfile.type) {
case NTO: s = ">"; dftfd = 1; break;
case NAPPEND: s = ">>"; dftfd = 1; break;
case NTOFD: s = ">&"; dftfd = 1; break;
case NFROM: s = "<"; dftfd = 0; break;
case NFROMFD: s = "<&"; dftfd = 0; break;
default: s = "*error*"; dftfd = 0; break;
}
if (np->nfile.fd != dftfd)
fprintf(fp, "%d", np->nfile.fd);
fputs(s, fp);
if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
fprintf(fp, "%d", np->ndup.dupfd);
} else {
sharg(np->nfile.fname, fp);
}
first = 0;
}
}
static void
sharg(arg, fp)
union node *arg;
FILE *fp;
{
char *p;
struct nodelist *bqlist;
int subtype;
if (arg->type != NARG) {
printf("<node type %d>\n", arg->type);
fflush(stdout);
abort();
}
bqlist = arg->narg.backquote;
for (p = arg->narg.text ; *p ; p++) {
switch (*p) {
case CTLESC:
putc(*++p, fp);
break;
case CTLVAR:
putc('$', fp);
putc('{', fp);
subtype = *++p;
if (subtype == VSLENGTH)
putc('#', fp);
while (*p != '=')
putc(*p++, fp);
if (subtype & VSNUL)
putc(':', fp);
switch (subtype & VSTYPE) {
case VSNORMAL:
putc('}', fp);
break;
case VSMINUS:
putc('-', fp);
break;
case VSPLUS:
putc('+', fp);
break;
case VSQUESTION:
putc('?', fp);
break;
case VSASSIGN:
putc('=', fp);
break;
case VSTRIMLEFT:
putc('#', fp);
break;
case VSTRIMLEFTMAX:
putc('#', fp);
putc('#', fp);
break;
case VSTRIMRIGHT:
putc('%', fp);
break;
case VSTRIMRIGHTMAX:
putc('%', fp);
putc('%', fp);
break;
case VSLENGTH:
break;
default:
printf("<subtype %d>", subtype);
}
break;
case CTLENDVAR:
putc('}', fp);
break;
case CTLBACKQ:
case CTLBACKQ|CTLQUOTE:
putc('$', fp);
putc('(', fp);
shtree(bqlist->n, -1, NULL, fp);
putc(')', fp);
break;
default:
putc(*p, fp);
break;
}
}
}
static void
indent(amount, pfx, fp)
int amount;
char *pfx;
FILE *fp;
{
int i;
for (i = 0 ; i < amount ; i++) {
if (pfx && i == amount - 1)
fputs(pfx, fp);
putc('\t', fp);
}
}
#endif
/*
* Debugging stuff.
*/
FILE *tracefile;
#if DEBUG == 2
int debug = 1;
#else
int debug = 0;
#endif
#ifdef DEBUG
void
trputc(c)
int c;
{
if (tracefile == NULL)
return;
putc(c, tracefile);
if (c == '\n')
fflush(tracefile);
}
#endif
void
#ifdef __STDC__
trace(const char *fmt, ...)
#else
trace(va_alist)
va_dcl
#endif
{
#ifdef DEBUG
va_list va;
#ifdef __STDC__
va_start(va, fmt);
#else
char *fmt;
va_start(va);
fmt = va_arg(va, char *);
#endif
if (tracefile != NULL) {
(void) vfprintf(tracefile, fmt, va);
if (strchr(fmt, '\n'))
(void) fflush(tracefile);
}
va_end(va);
#endif
}
#ifdef DEBUG
void
trputs(s)
char *s;
{
if (tracefile == NULL)
return;
fputs(s, tracefile);
if (strchr(s, '\n'))
fflush(tracefile);
}
static void
trstring(s)
char *s;
{
char *p;
char c;
if (tracefile == NULL)
return;
putc('"', tracefile);
for (p = s ; *p ; p++) {
switch (*p) {
case '\n': c = 'n'; goto backslash;
case '\t': c = 't'; goto backslash;
case '\r': c = 'r'; goto backslash;
case '"': c = '"'; goto backslash;
case '\\': c = '\\'; goto backslash;
case CTLESC: c = 'e'; goto backslash;
case CTLVAR: c = 'v'; goto backslash;
case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
case CTLBACKQ: c = 'q'; goto backslash;
case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
backslash: putc('\\', tracefile);
putc(c, tracefile);
break;
default:
if (*p >= ' ' && *p <= '~')
putc(*p, tracefile);
else {
putc('\\', tracefile);
putc(*p >> 6 & 03, tracefile);
putc(*p >> 3 & 07, tracefile);
putc(*p & 07, tracefile);
}
break;
}
}
putc('"', tracefile);
}
#endif
void
trargs(ap)
char **ap;
{
#ifdef DEBUG
if (tracefile == NULL)
return;
while (*ap) {
trstring(*ap++);
if (*ap)
putc(' ', tracefile);
else
putc('\n', tracefile);
}
fflush(tracefile);
#endif
}
#ifdef DEBUG
void
opentrace() {
char s[100];
char *getenv();
#ifdef O_APPEND
int flags;
#endif
if (!debug)
return;
#ifdef not_this_way
{
char *p;
if ((p = getenv("HOME")) == NULL) {
if (geteuid() == 0)
p = "/";
else
p = "/tmp";
}
scopy(p, s);
strcat(s, "/trace");
}
#else
scopy("./trace", s);
#endif /* not_this_way */
if ((tracefile = fopen(s, "a")) == NULL) {
fprintf(stderr, "Can't open %s\n", s);
return;
}
#ifdef O_APPEND
if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
#endif
fputs("\nTracing started.\n", tracefile);
fflush(tracefile);
}
#endif /* DEBUG */

View File

@ -1,46 +0,0 @@
/* $NetBSD: show.h,v 1.3 1997/04/11 22:58:40 christos Exp $ */
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)show.h 1.1 (Berkeley) 5/4/95
*/
union node;
void showtree __P((union node *));
void trace __P((const char *, ...));
void trargs __P((char **));
#ifdef DEBUG
void trputc __P((int));
void trputs __P((char *));
void opentrace __P((void));
#endif

View File

@ -1,383 +0,0 @@
/* $NetBSD: trap.c,v 1.17 1997/07/04 21:02:24 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
#else
__RCSID("$NetBSD: trap.c,v 1.17 1997/07/04 21:02:24 christos Exp $");
#endif
#endif /* not lint */
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#include "main.h"
#include "nodes.h" /* for other headers */
#include "eval.h"
#include "jobs.h"
#include "show.h"
#include "options.h"
#include "syntax.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "trap.h"
#include "mystring.h"
/*
* Sigmode records the current value of the signal handlers for the various
* modes. A value of zero means that the current handler is not known.
* S_HARD_IGN indicates that the signal was ignored on entry to the shell,
*/
#define S_DFL 1 /* default signal handling (SIG_DFL) */
#define S_CATCH 2 /* signal is caught */
#define S_IGN 3 /* signal is ignored (SIG_IGN) */
#define S_HARD_IGN 4 /* signal is ignored permenantly */
#define S_RESET 5 /* temporary - to reset a hard ignored sig */
extern char nullstr[1]; /* null string */
char *trap[NSIG+1]; /* trap handler commands */
MKINIT char sigmode[NSIG]; /* current value of signal */
char gotsig[NSIG]; /* indicates specified signal received */
int pendingsigs; /* indicates some signal received */
static int getsigaction __P((int, sig_t *));
/*
* The trap builtin.
*/
int
trapcmd(argc, argv)
int argc;
char **argv;
{
char *action;
char **ap;
int signo;
if (argc <= 1) {
for (signo = 0 ; signo <= NSIG ; signo++) {
if (trap[signo] != NULL)
out1fmt("%d: %s\n", signo, trap[signo]);
}
return 0;
}
ap = argv + 1;
if (is_number(*ap))
action = NULL;
else
action = *ap++;
while (*ap) {
if ((signo = number(*ap)) < 0 || signo > NSIG)
error("%s: bad trap", *ap);
INTOFF;
if (action)
action = savestr(action);
if (trap[signo])
ckfree(trap[signo]);
trap[signo] = action;
if (signo != 0)
setsignal(signo);
INTON;
ap++;
}
return 0;
}
/*
* Clear traps on a fork.
*/
void
clear_traps() {
char **tp;
for (tp = trap ; tp <= &trap[NSIG] ; tp++) {
if (*tp && **tp) { /* trap not NULL or SIG_IGN */
INTOFF;
ckfree(*tp);
*tp = NULL;
if (tp != &trap[0])
setsignal(tp - trap);
INTON;
}
}
}
/*
* Set the signal handler for the specified signal. The routine figures
* out what it should be set to.
*/
long
setsignal(signo)
int signo;
{
int action;
sig_t sigact = SIG_DFL;
char *t;
if ((t = trap[signo]) == NULL)
action = S_DFL;
else if (*t != '\0')
action = S_CATCH;
else
action = S_IGN;
if (rootshell && action == S_DFL) {
switch (signo) {
case SIGINT:
if (iflag)
action = S_CATCH;
break;
case SIGQUIT:
#ifdef DEBUG
{
extern int debug;
if (debug)
break;
}
#endif
/* FALLTHROUGH */
case SIGTERM:
if (iflag)
action = S_IGN;
break;
#if JOBS
case SIGTSTP:
case SIGTTOU:
if (mflag)
action = S_IGN;
break;
#endif
}
}
t = &sigmode[signo - 1];
if (*t == 0) {
/*
* current setting unknown
*/
if (!getsigaction(signo, &sigact)) {
/*
* Pretend it worked; maybe we should give a warning
* here, but other shells don't. We don't alter
* sigmode, so that we retry every time.
*/
return 0;
}
if (sigact == SIG_IGN) {
if (mflag && (signo == SIGTSTP ||
signo == SIGTTIN || signo == SIGTTOU)) {
*t = S_IGN; /* don't hard ignore these */
} else
*t = S_HARD_IGN;
} else {
*t = S_RESET; /* force to be set */
}
}
if (*t == S_HARD_IGN || *t == action)
return 0;
switch (action) {
case S_DFL: sigact = SIG_DFL; break;
case S_CATCH: sigact = onsig; break;
case S_IGN: sigact = SIG_IGN; break;
}
*t = action;
return (long)signal(signo, sigact);
}
/*
* Return the current setting for sig w/o changing it.
*/
static int
getsigaction(signo, sigact)
int signo;
sig_t *sigact;
{
struct sigaction sa;
if (sigaction(signo, (struct sigaction *)0, &sa) == -1)
return 0;
*sigact = (sig_t) sa.sa_handler;
return 1;
}
/*
* Ignore a signal.
*/
void
ignoresig(signo)
int signo;
{
if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
signal(signo, SIG_IGN);
}
sigmode[signo - 1] = S_HARD_IGN;
}
#ifdef mkinit
INCLUDE <signal.h>
INCLUDE "trap.h"
SHELLPROC {
char *sm;
clear_traps();
for (sm = sigmode ; sm < sigmode + NSIG ; sm++) {
if (*sm == S_IGN)
*sm = S_HARD_IGN;
}
}
#endif
/*
* Signal handler.
*/
void
onsig(signo)
int signo;
{
signal(signo, onsig);
if (signo == SIGINT && trap[SIGINT] == NULL) {
onint();
return;
}
gotsig[signo - 1] = 1;
pendingsigs++;
}
/*
* Called to execute a trap. Perhaps we should avoid entering new trap
* handlers while we are executing a trap handler.
*/
void
dotrap() {
int i;
int savestatus;
for (;;) {
for (i = 1 ; ; i++) {
if (gotsig[i - 1])
break;
if (i >= NSIG)
goto done;
}
gotsig[i - 1] = 0;
savestatus=exitstatus;
evalstring(trap[i]);
exitstatus=savestatus;
}
done:
pendingsigs = 0;
}
/*
* Controls whether the shell is interactive or not.
*/
void
setinteractive(on)
int on;
{
static int is_interactive;
if (on == is_interactive)
return;
setsignal(SIGINT);
setsignal(SIGQUIT);
setsignal(SIGTERM);
is_interactive = on;
}
/*
* Called to exit the shell.
*/
void
exitshell(status)
int status;
{
struct jmploc loc1, loc2;
char *p;
TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
if (setjmp(loc1.loc)) {
goto l1;
}
if (setjmp(loc2.loc)) {
goto l2;
}
handler = &loc1;
if ((p = trap[0]) != NULL && *p != '\0') {
trap[0] = NULL;
evalstring(p);
}
l1: handler = &loc2; /* probably unnecessary */
flushall();
#if JOBS
setjobctl(0);
#endif
l2: _exit(status);
}

View File

@ -1,50 +0,0 @@
/* $NetBSD: trap.h,v 1.11 1996/10/16 15:45:20 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)trap.h 8.3 (Berkeley) 6/5/95
*/
extern int pendingsigs;
int trapcmd __P((int, char **));
void clear_traps __P((void));
long setsignal __P((int));
void ignoresig __P((int));
void onsig __P((int));
void dotrap __P((void));
void setinteractive __P((int));
void exitshell __P((int));

View File

@ -1,754 +0,0 @@
/* $NetBSD: var.c,v 1.19 1997/07/04 21:02:25 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: var.c,v 1.19 1997/07/04 21:02:25 christos Exp $");
#endif
#endif /* not lint */
#include <unistd.h>
#include <stdlib.h>
/*
* Shell variables.
*/
#include "shell.h"
#include "output.h"
#include "expand.h"
#include "nodes.h" /* for other headers */
#include "eval.h" /* defines cmdenviron */
#include "exec.h"
#include "syntax.h"
#include "options.h"
#include "mail.h"
#include "var.h"
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "parser.h"
#ifndef SMALL
#include "myhistedit.h"
#endif
#define VTABSIZE 39
struct varinit {
struct var *var;
int flags;
char *text;
void (*func) __P((const char *));
};
#if ATTY
struct var vatty;
#endif
#ifndef SMALL
struct var vhistsize;
struct var vterm;
#endif
struct var vifs;
struct var vmail;
struct var vmpath;
struct var vpath;
struct var vps1;
struct var vps2;
struct var vvers;
struct var voptind;
const struct varinit varinit[] = {
#if ATTY
{ &vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY=",
NULL },
#endif
#ifndef SMALL
{ &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=",
sethistsize },
#endif
{ &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n",
NULL },
{ &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=",
NULL },
{ &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=",
NULL },
{ &vpath, VSTRFIXED|VTEXTFIXED, "PATH=/bin:/usr/bin",
changepath },
/*
* vps1 depends on uid
*/
{ &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
NULL },
#ifndef SMALL
{ &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=",
setterm },
#endif
{ &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
getoptsreset },
{ NULL, 0, NULL,
NULL }
};
struct var *vartab[VTABSIZE];
STATIC struct var **hashvar __P((char *));
STATIC int varequal __P((char *, char *));
/*
* Initialize the varable symbol tables and import the environment
*/
#ifdef mkinit
INCLUDE "var.h"
INIT {
char **envp;
extern char **environ;
initvar();
for (envp = environ ; *envp ; envp++) {
if (strchr(*envp, '=')) {
setvareq(*envp, VEXPORT|VTEXTFIXED);
}
}
}
#endif
/*
* This routine initializes the builtin variables. It is called when the
* shell is initialized and again when a shell procedure is spawned.
*/
void
initvar() {
const struct varinit *ip;
struct var *vp;
struct var **vpp;
for (ip = varinit ; (vp = ip->var) != NULL ; ip++) {
if ((vp->flags & VEXPORT) == 0) {
vpp = hashvar(ip->text);
vp->next = *vpp;
*vpp = vp;
vp->text = ip->text;
vp->flags = ip->flags;
vp->func = ip->func;
}
}
/*
* PS1 depends on uid
*/
if ((vps1.flags & VEXPORT) == 0) {
vpp = hashvar("PS1=");
vps1.next = *vpp;
*vpp = &vps1;
vps1.text = geteuid() ? "PS1=$ " : "PS1=# ";
vps1.flags = VSTRFIXED|VTEXTFIXED;
}
}
/*
* Safe version of setvar, returns 1 on success 0 on failure.
*/
int
setvarsafe(name, val, flags)
char *name, *val;
int flags;
{
struct jmploc jmploc;
struct jmploc *volatile savehandler = handler;
int err = 0;
#ifdef __GNUC__
(void) &err;
#endif
if (setjmp(jmploc.loc))
err = 1;
else {
handler = &jmploc;
setvar(name, val, flags);
}
handler = savehandler;
return err;
}
/*
* Set the value of a variable. The flags argument is ored with the
* flags of the variable. If val is NULL, the variable is unset.
*/
void
setvar(name, val, flags)
char *name, *val;
int flags;
{
char *p, *q;
int len;
int namelen;
char *nameeq;
int isbad;
isbad = 0;
p = name;
if (! is_name(*p))
isbad = 1;
p++;
for (;;) {
if (! is_in_name(*p)) {
if (*p == '\0' || *p == '=')
break;
isbad = 1;
}
p++;
}
namelen = p - name;
if (isbad)
error("%.*s: bad variable name", namelen, name);
len = namelen + 2; /* 2 is space for '=' and '\0' */
if (val == NULL) {
flags |= VUNSET;
} else {
len += strlen(val);
}
p = nameeq = ckmalloc(len);
q = name;
while (--namelen >= 0)
*p++ = *q++;
*p++ = '=';
*p = '\0';
if (val)
scopy(val, p);
setvareq(nameeq, flags);
}
/*
* Same as setvar except that the variable and value are passed in
* the first argument as name=value. Since the first argument will
* be actually stored in the table, it should not be a string that
* will go away.
*/
void
setvareq(s, flags)
char *s;
int flags;
{
struct var *vp, **vpp;
vpp = hashvar(s);
for (vp = *vpp ; vp ; vp = vp->next) {
if (varequal(s, vp->text)) {
if (vp->flags & VREADONLY) {
size_t len = strchr(s, '=') - s;
error("%.*s: is read only", len, s);
}
INTOFF;
if (vp->func && (flags & VNOFUNC) == 0)
(*vp->func)(strchr(s, '=') + 1);
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
ckfree(vp->text);
vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
vp->flags |= flags;
vp->text = s;
/*
* We could roll this to a function, to handle it as
* a regular variable function callback, but why bother?
*/
if (vp == &vmpath || (vp == &vmail && ! mpathset()))
chkmail(1);
INTON;
return;
}
}
/* not found */
vp = ckmalloc(sizeof (*vp));
vp->flags = flags;
vp->text = s;
vp->next = *vpp;
vp->func = NULL;
*vpp = vp;
}
/*
* Process a linked list of variable assignments.
*/
void
listsetvar(list)
struct strlist *list;
{
struct strlist *lp;
INTOFF;
for (lp = list ; lp ; lp = lp->next) {
setvareq(savestr(lp->text), 0);
}
INTON;
}
/*
* Find the value of a variable. Returns NULL if not set.
*/
char *
lookupvar(name)
char *name;
{
struct var *v;
for (v = *hashvar(name) ; v ; v = v->next) {
if (varequal(v->text, name)) {
if (v->flags & VUNSET)
return NULL;
return strchr(v->text, '=') + 1;
}
}
return NULL;
}
/*
* Search the environment of a builtin command. If the second argument
* is nonzero, return the value of a variable even if it hasn't been
* exported.
*/
char *
bltinlookup(name, doall)
char *name;
int doall;
{
struct strlist *sp;
struct var *v;
for (sp = cmdenviron ; sp ; sp = sp->next) {
if (varequal(sp->text, name))
return strchr(sp->text, '=') + 1;
}
for (v = *hashvar(name) ; v ; v = v->next) {
if (varequal(v->text, name)) {
if ((v->flags & VUNSET)
|| (!doall && (v->flags & VEXPORT) == 0))
return NULL;
return strchr(v->text, '=') + 1;
}
}
return NULL;
}
/*
* Generate a list of exported variables. This routine is used to construct
* the third argument to execve when executing a program.
*/
char **
environment() {
int nenv;
struct var **vpp;
struct var *vp;
char **env, **ep;
nenv = 0;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next)
if (vp->flags & VEXPORT)
nenv++;
}
ep = env = stalloc((nenv + 1) * sizeof *env);
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next)
if (vp->flags & VEXPORT)
*ep++ = vp->text;
}
*ep = NULL;
return env;
}
/*
* Called when a shell procedure is invoked to clear out nonexported
* variables. It is also necessary to reallocate variables of with
* VSTACK set since these are currently allocated on the stack.
*/
#ifdef mkinit
MKINIT void shprocvar __P((void));
SHELLPROC {
shprocvar();
}
#endif
void
shprocvar() {
struct var **vpp;
struct var *vp, **prev;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (prev = vpp ; (vp = *prev) != NULL ; ) {
if ((vp->flags & VEXPORT) == 0) {
*prev = vp->next;
if ((vp->flags & VTEXTFIXED) == 0)
ckfree(vp->text);
if ((vp->flags & VSTRFIXED) == 0)
ckfree(vp);
} else {
if (vp->flags & VSTACK) {
vp->text = savestr(vp->text);
vp->flags &=~ VSTACK;
}
prev = &vp->next;
}
}
}
initvar();
}
/*
* Command to list all variables which are set. Currently this command
* is invoked from the set command when the set command is called without
* any variables.
*/
int
showvarscmd(argc, argv)
int argc;
char **argv;
{
struct var **vpp;
struct var *vp;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next) {
if ((vp->flags & VUNSET) == 0)
out1fmt("%s\n", vp->text);
}
}
return 0;
}
/*
* The export and readonly commands.
*/
int
exportcmd(argc, argv)
int argc;
char **argv;
{
struct var **vpp;
struct var *vp;
char *name;
char *p;
int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
listsetvar(cmdenviron);
if (argc > 1) {
while ((name = *argptr++) != NULL) {
if ((p = strchr(name, '=')) != NULL) {
p++;
} else {
vpp = hashvar(name);
for (vp = *vpp ; vp ; vp = vp->next) {
if (varequal(vp->text, name)) {
vp->flags |= flag;
goto found;
}
}
}
setvar(name, p, flag);
found:;
}
} else {
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next) {
if (vp->flags & flag) {
for (p = vp->text ; *p != '=' ; p++)
out1c(*p);
out1c('\n');
}
}
}
}
return 0;
}
/*
* The "local" command.
*/
int
localcmd(argc, argv)
int argc;
char **argv;
{
char *name;
if (! in_function())
error("Not in a function");
while ((name = *argptr++) != NULL) {
mklocal(name);
}
return 0;
}
/*
* Make a variable a local variable. When a variable is made local, it's
* value and flags are saved in a localvar structure. The saved values
* will be restored when the shell function returns. We handle the name
* "-" as a special case.
*/
void
mklocal(name)
char *name;
{
struct localvar *lvp;
struct var **vpp;
struct var *vp;
INTOFF;
lvp = ckmalloc(sizeof (struct localvar));
if (name[0] == '-' && name[1] == '\0') {
lvp->text = ckmalloc(sizeof optlist);
memcpy(lvp->text, optlist, sizeof optlist);
vp = NULL;
} else {
vpp = hashvar(name);
for (vp = *vpp ; vp && ! varequal(vp->text, name) ; vp = vp->next);
if (vp == NULL) {
if (strchr(name, '='))
setvareq(savestr(name), VSTRFIXED);
else
setvar(name, NULL, VSTRFIXED);
vp = *vpp; /* the new variable */
lvp->text = NULL;
lvp->flags = VUNSET;
} else {
lvp->text = vp->text;
lvp->flags = vp->flags;
vp->flags |= VSTRFIXED|VTEXTFIXED;
if (strchr(name, '='))
setvareq(savestr(name), 0);
}
}
lvp->vp = vp;
lvp->next = localvars;
localvars = lvp;
INTON;
}
/*
* Called after a function returns.
*/
void
poplocalvars() {
struct localvar *lvp;
struct var *vp;
while ((lvp = localvars) != NULL) {
localvars = lvp->next;
vp = lvp->vp;
if (vp == NULL) { /* $- saved */
memcpy(optlist, lvp->text, sizeof optlist);
ckfree(lvp->text);
} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
(void)unsetvar(vp->text);
} else {
if ((vp->flags & VTEXTFIXED) == 0)
ckfree(vp->text);
vp->flags = lvp->flags;
vp->text = lvp->text;
}
ckfree(lvp);
}
}
int
setvarcmd(argc, argv)
int argc;
char **argv;
{
if (argc <= 2)
return unsetcmd(argc, argv);
else if (argc == 3)
setvar(argv[1], argv[2], 0);
else
error("List assignment not implemented");
return 0;
}
/*
* The unset builtin command. We unset the function before we unset the
* variable to allow a function to be unset when there is a readonly variable
* with the same name.
*/
int
unsetcmd(argc, argv)
int argc;
char **argv;
{
char **ap;
int i;
int flg_func = 0;
int flg_var = 0;
int ret = 0;
while ((i = nextopt("vf")) != '\0') {
if (i == 'f')
flg_func = 1;
else
flg_var = 1;
}
if (flg_func == 0 && flg_var == 0)
flg_var = 1;
for (ap = argptr; *ap ; ap++) {
if (flg_func)
ret |= unsetfunc(*ap);
if (flg_var)
ret |= unsetvar(*ap);
}
return ret;
}
/*
* Unset the specified variable.
*/
int
unsetvar(s)
char *s;
{
struct var **vpp;
struct var *vp;
vpp = hashvar(s);
for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
if (varequal(vp->text, s)) {
if (vp->flags & VREADONLY)
return (1);
INTOFF;
if (*(strchr(vp->text, '=') + 1) != '\0')
setvar(s, nullstr, 0);
vp->flags &= ~VEXPORT;
vp->flags |= VUNSET;
if ((vp->flags & VSTRFIXED) == 0) {
if ((vp->flags & VTEXTFIXED) == 0)
ckfree(vp->text);
*vpp = vp->next;
ckfree(vp);
}
INTON;
return (0);
}
}
return (1);
}
/*
* Find the appropriate entry in the hash table from the name.
*/
STATIC struct var **
hashvar(p)
char *p;
{
unsigned int hashval;
hashval = ((unsigned char) *p) << 4;
while (*p && *p != '=')
hashval += (unsigned char) *p++;
return &vartab[hashval % VTABSIZE];
}
/*
* Returns true if the two strings specify the same varable. The first
* variable name is terminated by '='; the second may be terminated by
* either '=' or '\0'.
*/
STATIC int
varequal(p, q)
char *p, *q;
{
while (*p == *q++) {
if (*p++ == '=')
return 1;
}
if (*p == '=' && *(q - 1) == '\0')
return 1;
return 0;
}

View File

@ -1,130 +0,0 @@
/* $NetBSD: var.h,v 1.14 1997/04/11 22:45:40 christos Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)var.h 8.2 (Berkeley) 5/4/95
*/
/*
* Shell variables.
*/
/* flags */
#define VEXPORT 0x01 /* variable is exported */
#define VREADONLY 0x02 /* variable cannot be modified */
#define VSTRFIXED 0x04 /* variable struct is staticly allocated */
#define VTEXTFIXED 0x08 /* text is staticly allocated */
#define VSTACK 0x10 /* text is allocated on the stack */
#define VUNSET 0x20 /* the variable is not set */
#define VNOFUNC 0x40 /* don't call the callback function */
struct var {
struct var *next; /* next entry in hash list */
int flags; /* flags are defined above */
char *text; /* name=value */
void (*func) __P((const char *));
/* function to be called when */
/* the variable gets set/unset */
};
struct localvar {
struct localvar *next; /* next local variable in list */
struct var *vp; /* the variable that was made local */
int flags; /* saved flags */
char *text; /* saved text */
};
struct localvar *localvars;
#if ATTY
extern struct var vatty;
#endif
extern struct var vifs;
extern struct var vmail;
extern struct var vmpath;
extern struct var vpath;
extern struct var vps1;
extern struct var vps2;
#ifndef SMALL
extern struct var vterm;
extern struct var vtermcap;
extern struct var vhistsize;
#endif
/*
* The following macros access the values of the above variables.
* They have to skip over the name. They return the null string
* for unset variables.
*/
#define ifsval() (vifs.text + 4)
#define mailval() (vmail.text + 5)
#define mpathval() (vmpath.text + 9)
#define pathval() (vpath.text + 5)
#define ps1val() (vps1.text + 4)
#define ps2val() (vps2.text + 4)
#define optindval() (voptind.text + 7)
#ifndef SMALL
#define histsizeval() (vhistsize.text + 9)
#define termval() (vterm.text + 5)
#endif
#if ATTY
#define attyset() ((vatty.flags & VUNSET) == 0)
#endif
#define mpathset() ((vmpath.flags & VUNSET) == 0)
void initvar __P((void));
void setvar __P((char *, char *, int));
void setvareq __P((char *, int));
struct strlist;
void listsetvar __P((struct strlist *));
char *lookupvar __P((char *));
char *bltinlookup __P((char *, int));
char **environment __P((void));
void shprocvar __P((void));
int showvarscmd __P((int, char **));
int exportcmd __P((int, char **));
int localcmd __P((int, char **));
void mklocal __P((char *));
void poplocalvars __P((void));
int setvarcmd __P((int, char **));
int unsetcmd __P((int, char **));
int unsetvar __P((char *));
int setvarsafe __P((char *, char *, int));