With much regret, I had to remove these two programs - their license

doesn't permit us to distribute them. I think I should take some law
classes...

Explained by:	bde
This commit is contained in:
Andrzej Bialecki 1998-10-25 03:02:56 +00:00
parent a57faa7b13
commit f2c7b777e2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=40633
17 changed files with 0 additions and 9390 deletions

View file

@ -1,77 +0,0 @@
LICENSE AGREEMENT AND LIMITED WARRANTY
READ THE FOLLOWING TERMS AND CONDITIONS CAREFULLY BEFORE YOU
PROCEED. THIS LEGAL DOCUMENT IS AN AGREEMENT BETWEEN YOU AND
PRENTICE-HALL, INC. (THE "COMPANY"). BY ACCESSING THE SOFTWARE, YOU
ARE AGREEING TO BE BOUND BY THESE TERMS AND CONDITIONS. IF YOU DO
NOT AGREE WITH THESE TERMS AND CONDITIONS, DO NOT ACCESS TO SOFTWARE
AND ALL ACCOMPANYING ITEMS.
1. GRANT OF LICENSE:
In consideration of your agreement to abide by the terms and
conditions of this Agreement, the Company grants to you a
nonexclusive right to use, display and modify the Software being
transmitted to you (hereinafter "the Software") for educational and
research purposes and to include such Software as part of another
computer program (i) for use by you; or (ii) for use by third
parties, provided that copies to those third parties are distributed
for educational or research purposes free of direct or indirect
charges. If you wish to otherwise use or distribute the Software,
you must enter into a separate agreement with the Company. To do so,
please contact the person designated below.
This license shall continue in effect so long as you comply with the
terms of this Agreement and will automatically terminate if you fail
to comply. The Company is and shall remain the copyright owner of
the Software and reserves all rights not expressly granted to you
under this Agreement. All provisions of this Agreement as to
warranties, limitation of liability, remedies or damages and
ownership rights shall survive termination.
2. MISCELLANEOUS:
This Agreement shall be construed in accordance with the laws of the
United States of America and the State of New York and shall benefit
the Company, its affiliates and assignees.
3. LIMITED WARRANTY AND DISCLAIMER OF WARRANTY:
Because this Software is being given to you without charge, the
Company makes no warranties about the SOFTWARE, which is provided
"AS-IS." THE COMPANY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE COMPANY
DOES NOT WARRANT, GUARANTEE OR MAKE ANY REPRESENTATION REGARDING THE
USE OR THE RESULTS OF THE USE OF THE SOFTWARE. IN NO EVENT SHALL
THE COMPANY OR ITS EMPLOYEES, AGENTS, SUPPLIERS OR CONTRACTORS BE
LIABLE FOR ANY INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL
DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE LICENSE GRANTED
UNDER THIS AGREEMENT INCLUDING, WITHOUT LIMITATION, LOSS OF USE,
LOSS OF DATA, LOSS OF INCOME OR PROFIT, OR OTHER LOSSES SUSTAINED AS
A RESULT OF INJURY TO ANY PERSON, OR LOSS OF OR DAMAGE TO PROPERTY,
OR CLAIMS OF THIRD PARTIES, EVEN IF THE COMPANY OR AN AUTHORIZED
REPRESENTATIVE OF THE COMPANY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF IMPLIED WARRANTIES
OR LIABILITY FOR INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL
DAMAGES, SO THE ABOVE LIMITATIONS MAY NOT ALWAYS APPLY. YOU MAY HAVE
RIGHTS WHICH VARY IN ACCORDANCE WITH LOCAL LAW.
ACKNOWLEDGMENT
YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, UNDERSTAND IT AND
AGREE TO BE BOUND BY ITS TERMS AND CONDITIONS. YOU ALSO AGREE THAT
THIS AGREEMENT IS THE COMPLETE AND EXCLUSIVE STATEMENT OF THE
AGREEMENT BETWEEN YOU AND THE COMPANY AND SUPERSEDES ALL PROPOSALS
OR PRIOR AGREEMENTS, ORAL OR WRITTEN, AND ANY OTHER COMMUNICATIONS
BETWEEN YOU AND THE COMPANY OR ANY REPRESENTATIVE OF THE COMPANY
RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT.
Should you have any questions concerning this agreement or if you
wish to contact the Company for any reason, please contact
Alan Apt (alan_apt@prenhall.com)
Prentice Hall
2629 Redwing Rd.
Suite #260
Ft.Collins,CO 80526

View file

@ -1,18 +0,0 @@
# Makefile for mined
CFLAGS = -D_POSIX_SOURCE -DASSUME_CONS25
OBJ = mined1.o mined2.o
all: mined
mined: $(OBJ)
$(CC) -static -o $@ $(OBJ)
install: /usr/bin/mined
$(OBJ): mined.h
clean:
rm -f mined *.o *.s core *.bak

View file

@ -1,23 +0,0 @@
Warsaw, 1998.10.21
This is a port of Minix editor. It's small, fast and relatively
robust. It can perform basic editing commands, block operations,
and search and replace.
The keybindings are just plain insane. I added a help screen
(available under F1), and remapped some of the wildest keys to
function keys. If you have some time and a bit of hacking skills,
you're welcome to sanitize it. :-)
A bit of warning: one of the reasons for its small size is that it
doesn't use any termcap calls - it uses hardwired codes for 'cons25'
terminal type. If you try to use it with some other terminal, you
have to change them, or recompile with -DUNIX -ltermcap.
This is a copyrighted software - see the file LICENSE. It allows
you to use it for research and educational purposes only.
Andrzej Bialecki
<abial@FreeBSD.org>
$Id: README,v 1.1 1998/10/21 17:36:16 abial Exp $

View file

@ -1,377 +0,0 @@
/*========================================================================*
* Mined.h *
*========================================================================*/
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#ifndef YMAX
#ifdef UNIX
#include <stdio.h>
#undef putchar
#undef getchar
#undef NULL
#undef EOF
extern char *CE, *VS, *SO, *SE, *CL, *AL, *CM;
#define YMAX 49
#else
#define YMAX 24 /* Maximum y coordinate starting at 0 */
/* Escape sequences. */
extern char *enter_string; /* String printed on entering mined */
extern char *rev_video; /* String for starting reverse video */
extern char *normal_video; /* String for leaving reverse video */
extern char *rev_scroll; /* String for reverse scrolling */
extern char *pos_string; /* Absolute cursor positioning */
#define X_PLUS ' ' /* To be added to x for cursor sequence */
#define Y_PLUS ' ' /* To be added to y for cursor sequence */
#endif /* UNIX */
#define XMAX 79 /* Maximum x coordinate starting at 0*/
#define SCREENMAX (YMAX - 1) /* Number of lines displayed */
#define XBREAK (XMAX - 1) /* Line shift at this coordinate */
#define SHIFT_SIZE 25 /* Number of chars to shift */
#define SHIFT_MARK '!' /* Char indicating line continues */
#define MAX_CHARS 1024 /* Maximum chars on one line */
/* LINE_START must be rounded up to the lowest SHIFT_SIZE */
#define LINE_START (((-MAX_CHARS - 1) / SHIFT_SIZE) * SHIFT_SIZE \
- SHIFT_SIZE)
#define LINE_END (MAX_CHARS + 1) /* Highest x-coordinate for line */
#define LINE_LEN (XMAX + 1) /* Number of characters on line */
#define SCREEN_SIZE (XMAX * YMAX) /* Size of I/O buffering */
#define BLOCK_SIZE 1024
/* Return values of functions */
#define ERRORS -1
#define NO_LINE (ERRORS - 1) /* Must be < 0 */
#define FINE (ERRORS + 1)
#define NO_INPUT (ERRORS + 2)
#define STD_OUT 1 /* File descriptor for terminal */
#if (CHIP == INTEL)
#define MEMORY_SIZE (50 * 1024) /* Size of data space to malloc */
#endif
#define REPORT 2 /* Report change of lines on # lines */
typedef int FLAG;
/* General flags */
#define FALSE 0
#define TRUE 1
#define NOT_VALID 2
#define VALID 3
#define OFF 4
#define ON 5
/* Expression flags */
#define FORWARD 6
#define REVERSE 7
/* Yank flags */
#define SMALLER 8
#define BIGGER 9
#define SAME 10
#define EMPTY 11
#define NO_DELETE 12
#define DELETE 13
#define READ 14
#define WRITE 15
/*
* The Line structure. Each line entry contains a pointer to the next line,
* a pointer to the previous line, a pointer to the text and an unsigned char
* telling at which offset of the line printing should start (usually 0).
*/
struct Line {
struct Line *next;
struct Line *prev;
char *text;
unsigned char shift_count;
};
typedef struct Line LINE;
/* Dummy line indicator */
#define DUMMY 0x80
#define DUMMY_MASK 0x7F
/* Expression definitions */
#define NO_MATCH 0
#define MATCH 1
#define REG_ERROR 2
#define BEGIN_LINE (2 * REG_ERROR)
#define END_LINE (2 * BEGIN_LINE)
/*
* The regex structure. Status can be any of 0, BEGIN_LINE or REG_ERROR. In
* the last case, the result.err_mess field is assigned. Start_ptr and end_ptr
* point to the match found. For more details see the documentation file.
*/
struct regex {
union {
char *err_mess;
int *expression;
} result;
char status;
char *start_ptr;
char *end_ptr;
};
typedef struct regex REGEX;
/* NULL definitions */
#define NIL_PTR ((char *) 0)
#define NIL_LINE ((LINE *) 0)
#define NIL_REG ((REGEX *) 0)
#define NIL_INT ((int *) 0)
/*
* Forward declarations
*/
extern int nlines; /* Number of lines in file */
extern LINE *header; /* Head of line list */
extern LINE *tail; /* Last line in line list */
extern LINE *top_line; /* First line of screen */
extern LINE *bot_line; /* Last line of screen */
extern LINE *cur_line; /* Current line in use */
extern char *cur_text; /* Pointer to char on current line in use */
extern int last_y; /* Last y of screen. Usually SCREENMAX */
extern int ymax;
extern int screenmax;
extern char screen[SCREEN_SIZE];/* Output buffer for "writes" and "reads" */
extern int x, y; /* x, y coordinates on screen */
extern FLAG modified; /* Set when file is modified */
extern FLAG stat_visible; /* Set if status_line is visible */
extern FLAG writable; /* Set if file cannot be written */
extern FLAG quit; /* Set when quit character is typed */
extern FLAG rpipe; /* Set if file should be read from stdin */
extern int input_fd; /* Fd for command input */
extern FLAG loading; /* Set if we're loading a file */
extern int out_count; /* Index in output buffer */
extern char file_name[LINE_LEN]; /* Name of file in use */
extern char text_buffer[MAX_CHARS]; /* Buffer for modifying text */
extern char *blank_line; /* Clear line to end */
extern char yank_file[]; /* Temp file for buffer */
extern FLAG yank_status; /* Status of yank_file */
extern long chars_saved; /* Nr of chars saved in buffer */
/*
* Empty output buffer
*/
#define clear_buffer() (out_count = 0)
/*
* Print character on terminal
*/
#define putchar(c) (void) write_char(STD_OUT, (c))
/*
* Ring bell on terminal
*/
#define ring_bell() putchar('\07')
/*
* Print string on terminal
*/
#define string_print(str) (void) writeline(STD_OUT, (str))
/*
* Flush output buffer
*/
#define flush() (void) flush_buffer(STD_OUT)
/*
* Convert cnt to nearest tab position
*/
#define tab(cnt) (((cnt) + 8) & ~07)
#define is_tab(c) ((c) == '\t')
/*
* Word defenitions
*/
#define white_space(c) ((c) == ' ' || (c) == '\t')
#define alpha(c) ((c) != ' ' && (c) != '\t' && (c) != '\n')
/*
* Print line on terminal at offset 0 and clear tail of line
*/
#define line_print(line) put_line(line, 0, TRUE)
/*
* Move to coordinates and set textp. (Don't use address)
*/
#define move_to(nx, ny) move((nx), NIL_PTR, (ny))
/*
* Move to coordinates on screen as indicated by textp.
*/
#define move_address(address) move(0, (address), y)
/*
* Functions handling status_line. ON means in reverse video.
*/
#define status_line(str1, str2) (void) bottom_line(ON, (str1), \
(str2), NIL_PTR, FALSE)
#define error(str1, str2) (void) bottom_line(ON, (str1), \
(str2), NIL_PTR, FALSE)
#define get_string(str1,str2, fl) bottom_line(ON, (str1), NIL_PTR, (str2), fl)
#define clear_status() (void) bottom_line(OFF, NIL_PTR, NIL_PTR, \
NIL_PTR, FALSE)
/*
* Print info about current file and buffer.
*/
#define fstatus(mess, cnt) file_status((mess), (cnt), file_name, \
nlines, writable, modified)
/*
* Get real shift value.
*/
#define get_shift(cnt) ((cnt) & DUMMY_MASK)
#endif /* YMAX */
#ifdef __FreeBSD__
#define _PROTOTYPE(x,y) x ## y
#endif
/* mined1.c */
_PROTOTYPE(void FS, (void));
_PROTOTYPE(void VI, (void));
_PROTOTYPE(int WT, (void));
_PROTOTYPE(void XWT, (void));
_PROTOTYPE(void SH, (void));
_PROTOTYPE(LINE *proceed, (LINE *line, int count ));
_PROTOTYPE(int bottom_line, (FLAG revfl, char *s1, char *s2, char *inbuf, FLAG statfl ));
_PROTOTYPE(int count_chars, (LINE *line ));
_PROTOTYPE(void move, (int new_x, char *new_address, int new_y ));
_PROTOTYPE(int find_x, (LINE *line, char *address ));
_PROTOTYPE(char *find_address, (LINE *line, int x_coord, int *old_x ));
_PROTOTYPE(int length_of, (char *string ));
_PROTOTYPE(void copy_string, (char *to, char *from ));
_PROTOTYPE(void reset, (LINE *head_line, int screen_y ));
_PROTOTYPE(void set_cursor, (int nx, int ny ));
_PROTOTYPE(void open_device, (void));
_PROTOTYPE(int getchar, (void));
_PROTOTYPE(void display, (int x_coord, int y_coord, LINE *line, int count ));
_PROTOTYPE(int write_char, (int fd, int c ));
_PROTOTYPE(int writeline, (int fd, char *text ));
_PROTOTYPE(void put_line, (LINE *line, int offset, FLAG clear_line ));
_PROTOTYPE(int flush_buffer, (int fd ));
_PROTOTYPE(void bad_write, (int fd ));
_PROTOTYPE(void catch, (int sig ));
_PROTOTYPE(void abort_mined, (void));
_PROTOTYPE(void raw_mode, (FLAG state ));
_PROTOTYPE(void panic, (char *message ));
_PROTOTYPE(char *alloc, (int bytes ));
_PROTOTYPE(void free_space, (char *p ));
/*
#ifdef UNIX
_PROTOTYPE(void (*key_map [128]), (void));
#else
_PROTOTYPE(void (*key_map [256]), (void));
#endif
*/
_PROTOTYPE(void initialize, (void));
_PROTOTYPE(char *basename, (char *path ));
_PROTOTYPE(void load_file, (char *file ));
_PROTOTYPE(int get_line, (int fd, char *buffer ));
_PROTOTYPE(LINE *install_line, (char *buffer, int length ));
_PROTOTYPE(void main, (int argc, char *argv []));
_PROTOTYPE(void RD, (void));
_PROTOTYPE(void I, (void));
_PROTOTYPE(void XT, (void));
_PROTOTYPE(void ESC, (void));
_PROTOTYPE(int ask_save, (void));
_PROTOTYPE(int line_number, (void));
_PROTOTYPE(void file_status, (char *message, long count, char *file, int lines,
FLAG writefl, FLAG changed ));
#if __STDC__
void build_string(char *buf, char *fmt, ...);
#else
void build_string();
#endif
_PROTOTYPE(char *num_out, (long number ));
_PROTOTYPE(int get_number, (char *message, int *result ));
_PROTOTYPE(int input, (char *inbuf, FLAG clearfl ));
_PROTOTYPE(int get_file, (char *message, char *file ));
_PROTOTYPE(int _getchar, (void));
_PROTOTYPE(void _flush, (void));
_PROTOTYPE(void _putchar, (int c ));
_PROTOTYPE(void get_term, (void));
/* mined2.c */
_PROTOTYPE(void UP, (void));
_PROTOTYPE(void DN, (void));
_PROTOTYPE(void LF, (void));
_PROTOTYPE(void RT, (void));
_PROTOTYPE(void HIGH, (void));
_PROTOTYPE(void LOW, (void));
_PROTOTYPE(void BL, (void));
_PROTOTYPE(void EL, (void));
_PROTOTYPE(void GOTO, (void));
_PROTOTYPE(void HLP, (void));
_PROTOTYPE(void PD, (void));
_PROTOTYPE(void PU, (void));
_PROTOTYPE(void HO, (void));
_PROTOTYPE(void EF, (void));
_PROTOTYPE(void SU, (void));
_PROTOTYPE(void SD, (void));
_PROTOTYPE(int forward_scroll, (void));
_PROTOTYPE(int reverse_scroll, (void));
_PROTOTYPE(void MP, (void));
_PROTOTYPE(void move_previous_word, (FLAG remove ));
_PROTOTYPE(void MN, (void));
_PROTOTYPE(void move_next_word, (FLAG remove ));
_PROTOTYPE(void DCC, (void));
_PROTOTYPE(void DPC, (void));
_PROTOTYPE(void DLN, (void));
_PROTOTYPE(void DNW, (void));
_PROTOTYPE(void DPW, (void));
_PROTOTYPE(void S, (int character ));
_PROTOTYPE(void CTL, (void));
_PROTOTYPE(void LIB, (void));
_PROTOTYPE(LINE *line_insert, (LINE *line, char *string, int len ));
_PROTOTYPE(int insert, (LINE *line, char *location, char *string ));
_PROTOTYPE(LINE *line_delete, (LINE *line ));
_PROTOTYPE(void delete, (LINE *start_line, char *start_textp, LINE *end_line, char *end_textp ));
_PROTOTYPE(void PT, (void));
_PROTOTYPE(void IF, (void));
_PROTOTYPE(void file_insert, (int fd, FLAG old_pos ));
_PROTOTYPE(void WB, (void));
_PROTOTYPE(void MA, (void));
_PROTOTYPE(void YA, (void));
_PROTOTYPE(void DT, (void));
_PROTOTYPE(void set_up, (FLAG remove ));
_PROTOTYPE(FLAG checkmark, (void));
_PROTOTYPE(int legal, (void));
_PROTOTYPE(void yank, (LINE *start_line, char *start_textp, LINE *end_line, char *end_textp, FLAG remove ));
_PROTOTYPE(int scratch_file, (FLAG mode ));
_PROTOTYPE(void SF, (void));
_PROTOTYPE(void SR, (void));
_PROTOTYPE(REGEX *get_expression, (char *message ));
_PROTOTYPE(void GR, (void));
_PROTOTYPE(void LR, (void));
_PROTOTYPE(void change, (char *message, FLAG file ));
_PROTOTYPE(char *substitute, (LINE *line, REGEX *program, char *replacement ));
_PROTOTYPE(void search, (char *message, FLAG method ));
_PROTOTYPE(int find_y, (LINE *match_line ));
_PROTOTYPE(void finished, (REGEX *program, int *last_exp ));
_PROTOTYPE(void compile, (char *pattern, REGEX *program ));
_PROTOTYPE(LINE *match, (REGEX *program, char *string, FLAG method ));
_PROTOTYPE(int line_check, (REGEX *program, char *string, FLAG method ));
_PROTOTYPE(int check_string, (REGEX *program, char *string, int *expression ));
_PROTOTYPE(int star, (REGEX *program, char *end_position, char *string, int *expression ));
_PROTOTYPE(int in_list, (int *list, int c, int list_length, int opcode ));
_PROTOTYPE(void dummy_line, (void));

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,77 +0,0 @@
LICENSE AGREEMENT AND LIMITED WARRANTY
READ THE FOLLOWING TERMS AND CONDITIONS CAREFULLY BEFORE YOU
PROCEED. THIS LEGAL DOCUMENT IS AN AGREEMENT BETWEEN YOU AND
PRENTICE-HALL, INC. (THE "COMPANY"). BY ACCESSING THE SOFTWARE, YOU
ARE AGREEING TO BE BOUND BY THESE TERMS AND CONDITIONS. IF YOU DO
NOT AGREE WITH THESE TERMS AND CONDITIONS, DO NOT ACCESS TO SOFTWARE
AND ALL ACCOMPANYING ITEMS.
1. GRANT OF LICENSE:
In consideration of your agreement to abide by the terms and
conditions of this Agreement, the Company grants to you a
nonexclusive right to use, display and modify the Software being
transmitted to you (hereinafter "the Software") for educational and
research purposes and to include such Software as part of another
computer program (i) for use by you; or (ii) for use by third
parties, provided that copies to those third parties are distributed
for educational or research purposes free of direct or indirect
charges. If you wish to otherwise use or distribute the Software,
you must enter into a separate agreement with the Company. To do so,
please contact the person designated below.
This license shall continue in effect so long as you comply with the
terms of this Agreement and will automatically terminate if you fail
to comply. The Company is and shall remain the copyright owner of
the Software and reserves all rights not expressly granted to you
under this Agreement. All provisions of this Agreement as to
warranties, limitation of liability, remedies or damages and
ownership rights shall survive termination.
2. MISCELLANEOUS:
This Agreement shall be construed in accordance with the laws of the
United States of America and the State of New York and shall benefit
the Company, its affiliates and assignees.
3. LIMITED WARRANTY AND DISCLAIMER OF WARRANTY:
Because this Software is being given to you without charge, the
Company makes no warranties about the SOFTWARE, which is provided
"AS-IS." THE COMPANY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE COMPANY
DOES NOT WARRANT, GUARANTEE OR MAKE ANY REPRESENTATION REGARDING THE
USE OR THE RESULTS OF THE USE OF THE SOFTWARE. IN NO EVENT SHALL
THE COMPANY OR ITS EMPLOYEES, AGENTS, SUPPLIERS OR CONTRACTORS BE
LIABLE FOR ANY INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL
DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE LICENSE GRANTED
UNDER THIS AGREEMENT INCLUDING, WITHOUT LIMITATION, LOSS OF USE,
LOSS OF DATA, LOSS OF INCOME OR PROFIT, OR OTHER LOSSES SUSTAINED AS
A RESULT OF INJURY TO ANY PERSON, OR LOSS OF OR DAMAGE TO PROPERTY,
OR CLAIMS OF THIRD PARTIES, EVEN IF THE COMPANY OR AN AUTHORIZED
REPRESENTATIVE OF THE COMPANY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF IMPLIED WARRANTIES
OR LIABILITY FOR INCIDENTAL, INDIRECT, SPECIAL OR CONSEQUENTIAL
DAMAGES, SO THE ABOVE LIMITATIONS MAY NOT ALWAYS APPLY. YOU MAY HAVE
RIGHTS WHICH VARY IN ACCORDANCE WITH LOCAL LAW.
ACKNOWLEDGMENT
YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, UNDERSTAND IT AND
AGREE TO BE BOUND BY ITS TERMS AND CONDITIONS. YOU ALSO AGREE THAT
THIS AGREEMENT IS THE COMPLETE AND EXCLUSIVE STATEMENT OF THE
AGREEMENT BETWEEN YOU AND THE COMPANY AND SUPERSEDES ALL PROPOSALS
OR PRIOR AGREEMENTS, ORAL OR WRITTEN, AND ANY OTHER COMMUNICATIONS
BETWEEN YOU AND THE COMPANY OR ANY REPRESENTATIVE OF THE COMPANY
RELATING TO THE SUBJECT MATTER OF THIS AGREEMENT.
Should you have any questions concerning this agreement or if you
wish to contact the Company for any reason, please contact
Alan Apt (alan_apt@prenhall.com)
Prentice Hall
2629 Redwing Rd.
Suite #260
Ft.Collins,CO 80526

View file

@ -1,16 +0,0 @@
# Makefile for sh
CFLAGS = -O2 #-D_POSIX_SOURCE
LDFLAGS = -static
OBJ = sh1.o sh2.o sh3.o sh4.o sh5.o sh6.o
all: sh
sh: $(OBJ)
cc $(LDFLAGS) -o $@ $(OBJ)
$(OBJ): sh.h
clean:
rm -f sh *.o *.bak core

View file

@ -1,16 +0,0 @@
Warsaw, 1998.10.21
This is a port of Minix /bin/sh shell.
It's quite limited, but also quite small. One of most serious
limitations is lack of support for user-defined functions. Also,
globbing should be implemented with our glob(3) - the version in
sh4.c is rather primitive.
This is a copyrighted software - see the file LICENSE. In short,
it allows you to use it for research and educational purposes only.
Andrzej Bialecki
<abial@FreeBSD.org>
$Id: README,v 1.1 1998/10/21 17:36:28 abial Exp $

View file

@ -1,261 +0,0 @@
.TH SH 1
.SH NAME
sh, ., break, case, cd, continue, eval, exec, exit, export, for, if, read, readonly, set, shift, trap, umask, wait, while \- shell
.SH SYNOPSIS
\fBsh\fR [\fB\-eiknqstvxu\fR] [\fB\-c \fIstr\fR] \fB[\fIfile\fR]\fR
.br
.de FL
.TP
\\fB\\$1\\fR
\\$2
..
.de EX
.TP 20
\\fB\\$1\\fR
# \\$2
..
.SH OPTIONS
.FL "\-c" "Execute the commands in \fIstr\fR"
.FL "\-e" "Quit on error"
.FL "\-i" "Interactive mode; ignore QUIT, TERMINATE, INTERRUPT"
.FL "\-k" "Look for name=value everywhere on command line"
.FL "\-n" "Do not execute commands"
.FL "\-q" "Change qflag from sig_ign to sig_del"
.FL "\-s" "Read commands from standard input"
.FL "\-t" "Exit after reading and executing one command"
.FL "\-v" "Echo input lines as they are read"
.FL "\-x" "Trace"
.FL "\-u" "Unset variables"
.SH EXAMPLES
.EX "sh script" "Run a shell script"
.SH DESCRIPTION
.PP
.I Sh
is the shell, which forms the user's main interface with the system.
On startup, the shell reads /etc/profile and $HOME/.profile, if they exist,
and executes any commands they contain. The Minix shell has most of the
features of the V7 (Bourne) shell, including redirection of input and output,
pipes, magic characters, background processes, and shell scripts. A brief
summary follows, but whole books have been written on shell programming alone.
.LP
Some of the more common notations are:
.PP
.in +2.45i
.ta 2i 2.2i
.ti -2.2i
date # Regular command
.ti -2.2i
sort <file # Redirect \fIstdin\fR (standard input)
.ti -2.2i
sort <file1 >file2 # Redirect \fIstdin\fR and \fIstdout\fR
.ti -2.2i
cc file.c 2>error # Redirect \fIstderr\fR
.ti -2.2i
a.out >f 2>&1 # Combine standard output and standard error
.ti -2.2i
sort <file1 >>file2 # Append output to \fIfile2\fR
.ti -2.2i
sort <file1 >file2 & # Background job
.ti -2.2i
(ls \-l; a.out) & # Run two background commands sequentially
.ti -2.2i
sort <file | wc # Two-process pipeline
.ti -2.2i
sort <f | uniq | wc # Three-process pipeline
.ti -2.2i
ls \-l *.c # List all files ending in \fI.c\fR
.ti -2.2i
ls \-l [\fIa-c\fR]* # List all files beginning with \fIa\fR, \fIb\fR, or \fIc\fR
.ti -2.2i
ls \-l ? # List all one-character file names
.ti -2.2i
ls \e? # List the file whose name is question mark
.ti -2.2i
ls \(fm???\(fm # List the file whose name is three question marks
.ti -2.2i
v=/usr/ast # Set shell variable \fIv\fR
.ti -2.2i
ls \-l $v # Use shell variable \fIv\fR
.ti -2.2i
PS1=\(fmHi! \(fm # Change the primary prompt to \fIHi!\fR
.ti -2.2i
PS2=\(fmMore: \(fm # Change the secondary prompt to \fIMore:\fR
.ti -2.2i
ls \-l $HOME # List the home directory
.ti -2.2i
echo $PATH # Echo the search path
.ti -2.2i
echo $? # Echo exit status of previous command in decimal
.ti -2.2i
echo $$ # Echo shell's pid in decimal
.ti -2.2i
echo $! # Echo PID of last background process
.ti -2.2i
echo $# # Echo number of parameters (shell script)
.ti -2.2i
echo $2 # Echo second parameter (shell script)
.ti -2.2i
echo "$2" # Echo second parameter without expanding spaces
.ti -2.2i
echo $* # Echo all parameters (shell script)
.ti -2.2i
echo $@ # Echo all parameters (shell script)
.ti -2.2i
echo "$@" # Echo all parameters without expanding spaces
.in -2.45i
.LP
The shell uses the following variables for specific purposes:
.PP
.in +2.25i
.ta 2i
.ti -2i
SHELL the path of the current shell
.ti -2i
HOME the default value for the cd(1) command
.ti -2i
PATH the directories to be searched to find commands
.ti -2i
IFS the internal field separators for command strings
.ti -2i
PS1 the primary shell prompt
.ti -2i
PS2 the secondary shell prompt
.in -2.25i
.LP
There are various forms of substitution on the shell command line:
.PP
.in +2.25i
.ta 2i
.ti -2i
`...` Command string between back-quotes is replaced by its output
.ti -2i
"..." Permits variable substitution between quotes
.ti -2i
\&'...' Inhibits variable substitution between quotes
.ti -2i
$VAR Replaced by contents of variable VAR
.ti -2i
${VAR} Delimits variable VAR from any following string
.in -2.25i
.LP
The expressions below depend on whether or not VAR has ever been set.
If VAR has been set, they give:
.PP
.in +2.25i
.ta 2i
.ti -2i
${VAR-str} Replace expression by VAR, else by str
.ti -2i
${VAR=str} Replace expression by VAR, else by str and set VAR to str
.ti -2i
${VAR?str} Replace expression by VAR, else print str and exit shell
.ti -2i
${VAR+str} Replace expression by str, else by null string
.in -2.25i
.LP
If a colon is placed after VAR, the expressions depend on whether or not
VAR is currently set and non-null.
.LP
The shell has a number of built-in commands:
.PP
.in +2.25i
.ta 2i
.ti -2i
: return true status
.ti -2i
\&. fn execute shell script fn on current path
.ti -2i
break [n] break from a for, until or while loop; exit n levels
.ti -2i
continue [n] continue a for, until or while loop; resume nth loop
.ti -2i
cd [dir] change current working directory; move to $HOME
.ti -2i
eval cmd rescan cmd, performing substitutions
.ti -2i
eval rescan the current command line
.ti -2i
exec cmd execute cmd without creating a new process
.ti -2i
exec <|> with no command name, modify shell I/O
.ti -2i
exit [n] exit a shell program, with exit value n
.ti -2i
export [var] export var to shell's children; list exported variables
.ti -2i
pwd print the name of the current working directory
.ti -2i
read var read a line from stdin and assign to var
.ti -2i
readonly [var] make var readonly; list readonly variables
.ti -2i
set -f set shell flag (+f unsets flag)
.ti -2i
set str set positional parameter to str
.ti -2i
set show the current shell variables
.ti -2i
shift reassign positional parameters (except ${0}) one left
.ti -2i
times print accumulated user and system times for processes
.ti -2i
trap arg sigs trap signals sigs and run arg on receipt
.ti -2i
trap list trapped signals
.ti -2i
umask [n] set the user file creation mask; show the current umask
.ti -2i
wait [n] wait for process pid n; wait for all processes
.in -2.25i
.LP
The shell also contains a programming language, which has the following
operators and flow control statements:
.PP
.in +3.50i
.ta 2i 3.25i
.ti -3.25i
# Comment The rest of the line is ignored
.ti -3.25i
= Assignment Set a shell variable
.ti -3.25i
&& Logical AND Execute second command only if first succeeds
.ti -3.25i
|| Logical OR Execute second command only if first fails
.ti -3.25i
(...) Group Execute enclosed commands before continuing
.in -3.50i
.PP
.in +2.25i
.ta 2i
.ti -2i
for For loop (for ... in ... do ... done)
.ti -2i
case Case statement ((case ... ) ... ;; ... esac)
.ti -2i
esac Case statement end
.ti -2i
while While loop (while ... do ... done)
.ti -2i
do Do/For/While loop start (do ... until ...)
.ti -2i
done For/While loop end
.ti -2i
if Conditional statement (if ... else ... elif ... fi)
.ti -2i
in For loop selection
.ti -2i
then Conditional statement start
.ti -2i
else Conditional statement alternative
.ti -2i
elif Conditional statement end
.ti -2i
until Do loop end
.ti -2i
fi Conditional statement end
.in -2.25i
.SH "SEE ALSO"
.BR echo (1),
.BR expr (1),
.BR pwd (1),
.BR true (1).

View file

@ -1,388 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
/* Need a way to have void used for ANSI, nothing for K&R. */
#ifndef _ANSI
#undef _VOID
#define _VOID
#endif
/* -------- sh.h -------- */
/*
* shell
*/
#define LINELIM 2100
#define NPUSH 8 /* limit to input nesting */
#define NOFILE 20 /* Number of open files */
#define NUFILE 10 /* Number of user-accessible files */
#define FDBASE 10 /* First file usable by Shell */
/*
* values returned by wait
*/
#define WAITSIG(s) ((s)&0177)
#define WAITVAL(s) (((s)>>8)&0377)
#define WAITCORE(s) (((s)&0200)!=0)
/*
* library and system defintions
*/
#ifdef __STDC__
typedef void xint; /* base type of jmp_buf, for not broken compilers */
#else
typedef char * xint; /* base type of jmp_buf, for broken compilers */
#endif
/*
* shell components
*/
/* #include "area.h" */
/* #include "word.h" */
/* #include "io.h" */
/* #include "var.h" */
#define QUOTE 0200
#define NOBLOCK ((struct op *)NULL)
#define NOWORD ((char *)NULL)
#define NOWORDS ((char **)NULL)
#define NOPIPE ((int *)NULL)
/*
* Description of a command or an operation on commands.
* Might eventually use a union.
*/
struct op {
int type; /* operation type, see below */
char **words; /* arguments to a command */
struct ioword **ioact; /* IO actions (eg, < > >>) */
struct op *left;
struct op *right;
char *str; /* identifier for case and for */
};
#define TCOM 1 /* command */
#define TPAREN 2 /* (c-list) */
#define TPIPE 3 /* a | b */
#define TLIST 4 /* a [&;] b */
#define TOR 5 /* || */
#define TAND 6 /* && */
#define TFOR 7
#define TDO 8
#define TCASE 9
#define TIF 10
#define TWHILE 11
#define TUNTIL 12
#define TELIF 13
#define TPAT 14 /* pattern in case */
#define TBRACE 15 /* {c-list} */
#define TASYNC 16 /* c & */
/*
* actions determining the environment of a process
*/
#define BIT(i) (1<<(i))
#define FEXEC BIT(0) /* execute without forking */
/*
* flags to control evaluation of words
*/
#define DOSUB 1 /* interpret $, `, and quotes */
#define DOBLANK 2 /* perform blank interpretation */
#define DOGLOB 4 /* interpret [?* */
#define DOKEY 8 /* move words with `=' to 2nd arg. list */
#define DOTRIM 16 /* trim resulting string */
#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM)
Extern char **dolv;
Extern int dolc;
Extern int exstat;
Extern char gflg;
Extern int talking; /* interactive (talking-type wireless) */
Extern int execflg;
Extern int multiline; /* \n changed to ; */
Extern struct op *outtree; /* result from parser */
Extern xint *failpt;
Extern xint *errpt;
struct brkcon {
jmp_buf brkpt;
struct brkcon *nextlev;
} ;
Extern struct brkcon *brklist;
Extern int isbreak;
/*
* redirection
*/
struct ioword {
short io_unit; /* unit affected */
short io_flag; /* action (below) */
char *io_name; /* file name */
};
#define IOREAD 1 /* < */
#define IOHERE 2 /* << (here file) */
#define IOWRITE 4 /* > */
#define IOCAT 8 /* >> */
#define IOXHERE 16 /* ${}, ` in << */
#define IODUP 32 /* >&digit */
#define IOCLOSE 64 /* >&- */
#define IODEFAULT (-1) /* token for default IO unit */
Extern struct wdblock *wdlist;
Extern struct wdblock *iolist;
/*
* parsing & execution environment
*/
extern struct env {
char *linep;
struct io *iobase;
struct io *iop;
xint *errpt;
int iofd;
struct env *oenv;
} e;
/*
* flags:
* -e: quit on error
* -k: look for name=value everywhere on command line
* -n: no execution
* -t: exit after reading and executing one command
* -v: echo as read
* -x: trace
* -u: unset variables net diagnostic
*/
extern char *flag;
extern char *null; /* null value for variable */
extern int intr; /* interrupt pending */
Extern char *trap[_NSIG+1];
Extern char ourtrap[_NSIG+1];
Extern int trapset; /* trap pending */
extern int heedint; /* heed interrupt signals */
Extern int yynerrs; /* yacc */
Extern char line[LINELIM];
extern char *elinep;
/*
* other functions
*/
#ifdef __STDC__
int (*inbuilt(char *s ))(void);
#else
int (*inbuilt())();
#endif
#ifdef __FreeBSD__
#define _PROTOTYPE(x,y) x ## y
#endif
_PROTOTYPE(char *rexecve , (char *c , char **v , char **envp ));
_PROTOTYPE(char *space , (int n ));
_PROTOTYPE(char *strsave , (char *s , int a ));
_PROTOTYPE(char *evalstr , (char *cp , int f ));
_PROTOTYPE(char *putn , (int n ));
_PROTOTYPE(char *itoa , (unsigned u , int n ));
_PROTOTYPE(char *unquote , (char *as ));
_PROTOTYPE(struct var *lookup , (char *n ));
_PROTOTYPE(int rlookup , (char *n ));
_PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb ));
_PROTOTYPE(int subgetc , (int ec , int quoted ));
_PROTOTYPE(char **makenv , (void));
_PROTOTYPE(char **eval , (char **ap , int f ));
_PROTOTYPE(int setstatus , (int s ));
_PROTOTYPE(int waitfor , (int lastpid , int canintr ));
_PROTOTYPE(void onintr , (int s )); /* SIGINT handler */
_PROTOTYPE(int newenv , (int f ));
_PROTOTYPE(void quitenv , (void));
_PROTOTYPE(void err , (char *s ));
_PROTOTYPE(int anys , (char *s1 , char *s2 ));
_PROTOTYPE(int any , (int c , char *s ));
_PROTOTYPE(void next , (int f ));
_PROTOTYPE(void setdash , (void));
_PROTOTYPE(void onecommand , (void));
_PROTOTYPE(void runtrap , (int i ));
_PROTOTYPE(void xfree , (char *s ));
_PROTOTYPE(int letter , (int c ));
_PROTOTYPE(int digit , (int c ));
_PROTOTYPE(int letnum , (int c ));
_PROTOTYPE(int gmatch , (char *s , char *p ));
/*
* error handling
*/
_PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */
_PROTOTYPE(void fail , (void)); /* fail but return to process next command */
_PROTOTYPE(void warn , (char *s ));
_PROTOTYPE(void sig , (int i )); /* default signal handler */
/* -------- var.h -------- */
struct var {
char *value;
char *name;
struct var *next;
char status;
};
#define COPYV 1 /* flag to setval, suggesting copy */
#define RONLY 01 /* variable is read-only */
#define EXPORT 02 /* variable is to be exported */
#define GETCELL 04 /* name & value space was got with getcell */
Extern struct var *vlist; /* dictionary */
Extern struct var *homedir; /* home directory */
Extern struct var *prompt; /* main prompt */
Extern struct var *cprompt; /* continuation prompt */
Extern struct var *path; /* search path for commands */
Extern struct var *shell; /* shell to interpret command files */
Extern struct var *ifs; /* field separators */
_PROTOTYPE(int yyparse , (void));
_PROTOTYPE(struct var *lookup , (char *n ));
_PROTOTYPE(void setval , (struct var *vp , char *val ));
_PROTOTYPE(void nameval , (struct var *vp , char *val , char *name ));
_PROTOTYPE(void export , (struct var *vp ));
_PROTOTYPE(void ronly , (struct var *vp ));
_PROTOTYPE(int isassign , (char *s ));
_PROTOTYPE(int checkname , (char *cp ));
_PROTOTYPE(int assign , (char *s , int cf ));
_PROTOTYPE(void putvlist , (int f , int out ));
_PROTOTYPE(int eqname , (char *n1 , char *n2 ));
_PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act ));
/* -------- io.h -------- */
/* io buffer */
struct iobuf {
unsigned id; /* buffer id */
char buf[512]; /* buffer */
char *bufp; /* pointer into buffer */
char *ebufp; /* pointer to end of buffer */
};
/* possible arguments to an IO function */
struct ioarg {
char *aword;
char **awordlist;
int afile; /* file descriptor */
unsigned afid; /* buffer id */
long afpos; /* file position */
struct iobuf *afbuf; /* buffer for this file */
};
Extern struct ioarg ioargstack[NPUSH];
#define AFID_NOBUF (~0)
#define AFID_ID 0
/* an input generator's state */
struct io {
int (*iofn)(_VOID);
struct ioarg *argp;
int peekc;
char prev; /* previous character read by readc() */
char nlcount; /* for `'s */
char xchar; /* for `'s */
char task; /* reason for pushed IO */
};
Extern struct io iostack[NPUSH];
#define XOTHER 0 /* none of the below */
#define XDOLL 1 /* expanding ${} */
#define XGRAVE 2 /* expanding `'s */
#define XIO 3 /* file IO */
/* in substitution */
#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL)
/*
* input generators for IO structure
*/
_PROTOTYPE(int nlchar , (struct ioarg *ap ));
_PROTOTYPE(int strchar , (struct ioarg *ap ));
_PROTOTYPE(int qstrchar , (struct ioarg *ap ));
_PROTOTYPE(int filechar , (struct ioarg *ap ));
_PROTOTYPE(int herechar , (struct ioarg *ap ));
_PROTOTYPE(int linechar , (struct ioarg *ap ));
_PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop ));
_PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop ));
_PROTOTYPE(int dolchar , (struct ioarg *ap ));
_PROTOTYPE(int wdchar , (struct ioarg *ap ));
_PROTOTYPE(void scraphere , (void));
_PROTOTYPE(void freehere , (int area ));
_PROTOTYPE(void gethere , (void));
_PROTOTYPE(void markhere , (char *s , struct ioword *iop ));
_PROTOTYPE(int herein , (char *hname , int xdoll ));
_PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID)));
/*
* IO functions
*/
_PROTOTYPE(int eofc , (void));
_PROTOTYPE(int getc , (int ec ));
_PROTOTYPE(int readc , (void));
_PROTOTYPE(void unget , (int c ));
_PROTOTYPE(void ioecho , (int c ));
_PROTOTYPE(void prs , (char *s ));
_PROTOTYPE(void putc , (int c ));
_PROTOTYPE(void prn , (unsigned u ));
_PROTOTYPE(void closef , (int i ));
_PROTOTYPE(void closeall , (void));
/*
* IO control
*/
_PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID)));
_PROTOTYPE(int remap , (int fd ));
_PROTOTYPE(int openpipe , (int *pv ));
_PROTOTYPE(void closepipe , (int *pv ));
_PROTOTYPE(struct io *setbase , (struct io *ip ));
extern struct ioarg temparg; /* temporary for PUSHIO */
#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen)))
#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
/* -------- word.h -------- */
#ifndef WORD_H
#define WORD_H 1
struct wdblock {
short w_bsize;
short w_nword;
/* bounds are arbitrary */
char *w_words[1];
};
_PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb ));
_PROTOTYPE(struct wdblock *newword , (int nw ));
_PROTOTYPE(char **getwords , (struct wdblock *wb ));
#endif
/* -------- area.h -------- */
/*
* storage allocation
*/
_PROTOTYPE(char *getcell , (unsigned nbytes ));
_PROTOTYPE(void garbage , (void));
_PROTOTYPE(void setarea , (char *cp , int a ));
_PROTOTYPE(int getarea , (char *cp ));
_PROTOTYPE(void freearea , (int a ));
_PROTOTYPE(void freecell , (char *cp ));
Extern int areanum; /* current allocation area */
#define NEW(type) (type *)getcell(sizeof(type))
#define DELETE(obj) freecell((char *)obj)

View file

@ -1,953 +0,0 @@
#define Extern extern
#include <sys/types.h>
#include <signal.h>
#define _NSIG NSIG
#include <errno.h>
#include <setjmp.h>
#include "sh.h"
/* -------- sh.c -------- */
/*
* shell
*/
/* #include "sh.h" */
int intr;
int inparse;
char flags['z'-'a'+1];
char *flag = flags-'a';
char *elinep = line+sizeof(line)-5;
char *null = "";
int heedint =1;
struct env e ={line, iostack, iostack-1,
(xint *)NULL, FDBASE, (struct env *)NULL};
extern char **environ; /* environment pointer */
/*
* default shell, search rules
*/
char shellname[] = "/bin/sh";
char search[] = ":/bin:/usr/bin";
_PROTOTYPE(void (*qflag), (int)) = SIG_IGN;
_PROTOTYPE(int main, (int argc, char **argv ));
_PROTOTYPE(int newfile, (char *s ));
_PROTOTYPE(static char *findeq, (char *cp ));
_PROTOTYPE(static char *cclass, (char *p, int sub ));
_PROTOTYPE(void initarea, (void));
int main(argc, argv)
int argc;
register char **argv;
{
register int f;
register char *s;
int cflag;
char *name, **ap;
int (*iof)();
initarea();
if ((ap = environ) != NULL) {
while (*ap)
assign(*ap++, !COPYV);
for (ap = environ; *ap;)
export(lookup(*ap++));
}
closeall();
areanum = 1;
shell = lookup("SHELL");
if (shell->value == null)
setval(shell, shellname);
export(shell);
homedir = lookup("HOME");
if (homedir->value == null)
setval(homedir, "/");
export(homedir);
setval(lookup("$"), itoa(getpid(), 5));
path = lookup("PATH");
if (path->value == null)
setval(path, search);
export(path);
ifs = lookup("IFS");
if (ifs->value == null)
setval(ifs, " \t\n");
prompt = lookup("PS1");
if (prompt->value == null)
#ifndef UNIXSHELL
setval(prompt, "$ ");
#else
setval(prompt, "% ");
#endif
if (geteuid() == 0) {
setval(prompt, "# ");
prompt->status &= ~EXPORT;
}
cprompt = lookup("PS2");
if (cprompt->value == null)
setval(cprompt, "> ");
iof = filechar;
cflag = 0;
name = *argv++;
if (--argc >= 1) {
if(argv[0][0] == '-' && argv[0][1] != '\0') {
for (s = argv[0]+1; *s; s++)
switch (*s) {
case 'c':
prompt->status &= ~EXPORT;
cprompt->status &= ~EXPORT;
setval(prompt, "");
setval(cprompt, "");
cflag = 1;
if (--argc > 0)
PUSHIO(aword, *++argv, iof = nlchar);
break;
case 'q':
qflag = SIG_DFL;
break;
case 's':
/* standard input */
break;
case 't':
prompt->status &= ~EXPORT;
setval(prompt, "");
iof = linechar;
break;
case 'i':
talking++;
default:
if (*s>='a' && *s<='z')
flag[*s]++;
}
} else {
argv--;
argc++;
}
if (iof == filechar && --argc > 0) {
setval(prompt, "");
setval(cprompt, "");
prompt->status &= ~EXPORT;
cprompt->status &= ~EXPORT;
if (newfile(name = *++argv))
exit(1);
}
}
setdash();
if (e.iop < iostack) {
PUSHIO(afile, 0, iof);
if (isatty(0) && isatty(1) && !cflag)
talking++;
}
signal(SIGQUIT, qflag);
if (name && name[0] == '-') {
talking++;
if ((f = open(".profile", 0)) >= 0)
next(remap(f));
if ((f = open("/etc/profile", 0)) >= 0)
next(remap(f));
}
if (talking)
signal(SIGTERM, sig);
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, onintr);
dolv = argv;
dolc = argc;
dolv[0] = name;
if (dolc > 1)
for (ap = ++argv; --argc > 0;)
if (assign(*ap = *argv++, !COPYV))
dolc--; /* keyword */
else
ap++;
setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc));
for (;;) {
if (talking && e.iop <= iostack)
prs(prompt->value);
onecommand();
}
}
void
setdash()
{
register char *cp, c;
char m['z'-'a'+1];
cp = m;
for (c='a'; c<='z'; c++)
if (flag[c])
*cp++ = c;
*cp = 0;
setval(lookup("-"), m);
}
int
newfile(s)
register char *s;
{
register f;
if (strcmp(s, "-") != 0) {
f = open(s, 0);
if (f < 0) {
prs(s);
err(": cannot open");
return(1);
}
} else
f = 0;
next(remap(f));
return(0);
}
void
onecommand()
{
register i;
jmp_buf m1;
while (e.oenv)
quitenv();
areanum = 1;
freehere(areanum);
freearea(areanum);
garbage();
wdlist = 0;
iolist = 0;
e.errpt = 0;
e.linep = line;
yynerrs = 0;
multiline = 0;
inparse = 1;
intr = 0;
execflg = 0;
setjmp(failpt = m1); /* Bruce Evans' fix */
if (setjmp(failpt = m1) || yyparse() || intr) {
while (e.oenv)
quitenv();
scraphere();
if (!talking && intr)
leave();
inparse = 0;
intr = 0;
return;
}
inparse = 0;
brklist = 0;
intr = 0;
execflg = 0;
if (!flag['n'])
execute(outtree, NOPIPE, NOPIPE, 0);
if (!talking && intr) {
execflg = 0;
leave();
}
if ((i = trapset) != 0) {
trapset = 0;
runtrap(i);
}
}
void
fail()
{
longjmp(failpt, 1);
/* NOTREACHED */
}
void
leave()
{
if (execflg)
fail();
scraphere();
freehere(1);
runtrap(0);
exit(exstat);
/* NOTREACHED */
}
void
warn(s)
register char *s;
{
if(*s) {
prs(s);
exstat = -1;
}
prs("\n");
if (flag['e'])
leave();
}
void
err(s)
char *s;
{
warn(s);
if (flag['n'])
return;
if (!talking)
leave();
if (e.errpt)
longjmp(e.errpt, 1);
closeall();
e.iop = e.iobase = iostack;
}
int
newenv(f)
int f;
{
register struct env *ep;
if (f) {
quitenv();
return(1);
}
ep = (struct env *) space(sizeof(*ep));
if (ep == NULL) {
while (e.oenv)
quitenv();
fail();
}
*ep = e;
e.oenv = ep;
e.errpt = errpt;
return(0);
}
void
quitenv()
{
register struct env *ep;
register fd;
if ((ep = e.oenv) != NULL) {
fd = e.iofd;
e = *ep;
/* should close `'d files */
DELETE(ep);
while (--fd >= e.iofd)
close(fd);
}
}
/*
* Is any character from s1 in s2?
*/
int
anys(s1, s2)
register char *s1, *s2;
{
while (*s1)
if (any(*s1++, s2))
return(1);
return(0);
}
/*
* Is character c in s?
*/
int
any(c, s)
register int c;
register char *s;
{
while (*s)
if (*s++ == c)
return(1);
return(0);
}
char *
putn(n)
register int n;
{
return(itoa(n, -1));
}
char *
itoa(u, n)
register unsigned u;
int n;
{
register char *cp;
static char s[20];
int m;
m = 0;
if (n < 0 && (int) u < 0) {
m++;
u = -u;
}
cp = s+sizeof(s);
*--cp = 0;
do {
*--cp = u%10 + '0';
u /= 10;
} while (--n > 0 || u);
if (m)
*--cp = '-';
return(cp);
}
void
next(f)
int f;
{
PUSHIO(afile, f, filechar);
}
void
onintr(s)
int s; /* ANSI C requires a parameter */
{
signal(SIGINT, onintr);
intr = 1;
if (talking) {
if (inparse) {
prs("\n");
fail();
}
}
else if (heedint) {
execflg = 0;
leave();
}
}
int
letter(c)
register c;
{
return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_');
}
int
digit(c)
register c;
{
return(c >= '0' && c <= '9');
}
int
letnum(c)
register c;
{
return(letter(c) || digit(c));
}
char *
space(n)
int n;
{
register char *cp;
if ((cp = getcell(n)) == 0)
err("out of string space");
return(cp);
}
char *
strsave(s, a)
register char *s;
int a;
{
register char *cp, *xp;
if ((cp = space(strlen(s)+1)) != NULL) {
setarea((char *)cp, a);
for (xp = cp; (*xp++ = *s++) != '\0';)
;
return(cp);
}
return("");
}
void
xfree(s)
register char *s;
{
DELETE(s);
}
/*
* trap handling
*/
void
sig(i)
register int i;
{
trapset = i;
signal(i, sig);
}
void runtrap(i)
int i;
{
char *trapstr;
if ((trapstr = trap[i]) == NULL)
return;
if (i == 0)
trap[i] = 0;
RUN(aword, trapstr, nlchar);
}
/* -------- var.c -------- */
/* #include "sh.h" */
/*
* Find the given name in the dictionary
* and return its value. If the name was
* not previously there, enter it now and
* return a null value.
*/
struct var *
lookup(n)
register char *n;
{
register struct var *vp;
register char *cp;
register int c;
static struct var dummy;
if (digit(*n)) {
dummy.name = n;
for (c = 0; digit(*n) && c < 1000; n++)
c = c*10 + *n-'0';
dummy.status = RONLY;
dummy.value = c <= dolc? dolv[c]: null;
return(&dummy);
}
for (vp = vlist; vp; vp = vp->next)
if (eqname(vp->name, n))
return(vp);
cp = findeq(n);
vp = (struct var *)space(sizeof(*vp));
if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) {
dummy.name = dummy.value = "";
return(&dummy);
}
for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++)
;
if (*cp == 0)
*cp = '=';
*++cp = 0;
setarea((char *)vp, 0);
setarea((char *)vp->name, 0);
vp->value = null;
vp->next = vlist;
vp->status = GETCELL;
vlist = vp;
return(vp);
}
/*
* give variable at `vp' the value `val'.
*/
void
setval(vp, val)
struct var *vp;
char *val;
{
nameval(vp, val, (char *)NULL);
}
/*
* if name is not NULL, it must be
* a prefix of the space `val',
* and end with `='.
* this is all so that exporting
* values is reasonably painless.
*/
void
nameval(vp, val, name)
register struct var *vp;
char *val, *name;
{
register char *cp, *xp;
char *nv;
int fl;
if (vp->status & RONLY) {
for (xp = vp->name; *xp && *xp != '=';)
putc(*xp++);
err(" is read-only");
return;
}
fl = 0;
if (name == NULL) {
xp = space(strlen(vp->name)+strlen(val)+2);
if (xp == 0)
return;
/* make string: name=value */
setarea((char *)xp, 0);
name = xp;
for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++)
;
if (*xp++ == 0)
xp[-1] = '=';
nv = xp;
for (cp = val; (*xp++ = *cp++) != '\0';)
;
val = nv;
fl = GETCELL;
}
if (vp->status & GETCELL)
xfree(vp->name); /* form new string `name=value' */
vp->name = name;
vp->value = val;
vp->status |= fl;
}
void
export(vp)
struct var *vp;
{
vp->status |= EXPORT;
}
void
ronly(vp)
struct var *vp;
{
if (letter(vp->name[0])) /* not an internal symbol ($# etc) */
vp->status |= RONLY;
}
int
isassign(s)
register char *s;
{
if (!letter((int)*s))
return(0);
for (; *s != '='; s++)
if (*s == 0 || !letnum(*s))
return(0);
return(1);
}
int
assign(s, cf)
register char *s;
int cf;
{
register char *cp;
struct var *vp;
if (!letter(*s))
return(0);
for (cp = s; *cp != '='; cp++)
if (*cp == 0 || !letnum(*cp))
return(0);
vp = lookup(s);
nameval(vp, ++cp, cf == COPYV? (char *)NULL: s);
if (cf != COPYV)
vp->status &= ~GETCELL;
return(1);
}
int
checkname(cp)
register char *cp;
{
if (!letter(*cp++))
return(0);
while (*cp)
if (!letnum(*cp++))
return(0);
return(1);
}
void
putvlist(f, out)
register int f, out;
{
register struct var *vp;
for (vp = vlist; vp; vp = vp->next)
if (vp->status & f && letter(*vp->name)) {
if (vp->status & EXPORT)
write(out, "export ", 7);
if (vp->status & RONLY)
write(out, "readonly ", 9);
write(out, vp->name, (int)(findeq(vp->name) - vp->name));
write(out, "\n", 1);
}
}
int
eqname(n1, n2)
register char *n1, *n2;
{
for (; *n1 != '=' && *n1 != 0; n1++)
if (*n2++ != *n1)
return(0);
return(*n2 == 0 || *n2 == '=');
}
static char *
findeq(cp)
register char *cp;
{
while (*cp != '\0' && *cp != '=')
cp++;
return(cp);
}
/* -------- gmatch.c -------- */
/*
* int gmatch(string, pattern)
* char *string, *pattern;
*
* Match a pattern as in sh(1).
*/
#define CMASK 0377
#define QUOTE 0200
#define QMASK (CMASK&~QUOTE)
#define NOT '!' /* might use ^ */
int
gmatch(s, p)
register char *s, *p;
{
register int sc, pc;
if (s == NULL || p == NULL)
return(0);
while ((pc = *p++ & CMASK) != '\0') {
sc = *s++ & QMASK;
switch (pc) {
case '[':
if ((p = cclass(p, sc)) == NULL)
return(0);
break;
case '?':
if (sc == 0)
return(0);
break;
case '*':
s--;
do {
if (*p == '\0' || gmatch(s, p))
return(1);
} while (*s++ != '\0');
return(0);
default:
if (sc != (pc&~QUOTE))
return(0);
}
}
return(*s == 0);
}
static char *
cclass(p, sub)
register char *p;
register int sub;
{
register int c, d, not, found;
if ((not = *p == NOT) != 0)
p++;
found = not;
do {
if (*p == '\0')
return((char *)NULL);
c = *p & CMASK;
if (p[1] == '-' && p[2] != ']') {
d = p[2] & CMASK;
p++;
} else
d = c;
if (c == sub || (c <= sub && sub <= d))
found = !not;
} while (*++p != ']');
return(found? p+1: (char *)NULL);
}
/* -------- area.c -------- */
#define REGSIZE sizeof(struct region)
#define GROWBY 256
#undef SHRINKBY 64
#define FREE 32767
#define BUSY 0
#define ALIGN (sizeof(int)-1)
/* #include "area.h" */
struct region {
struct region *next;
int area;
};
/*
* All memory between (char *)areabot and (char *)(areatop+1) is
* exclusively administered by the area management routines.
* It is assumed that sbrk() and brk() manipulate the high end.
*/
static struct region *areabot; /* bottom of area */
static struct region *areatop; /* top of area */
static struct region *areanxt; /* starting point of scan */
void
initarea()
{
while ((int)sbrk(0) & ALIGN)
sbrk(1);
areabot = (struct region *)sbrk(REGSIZE);
areabot->next = areabot;
areabot->area = BUSY;
areatop = areabot;
areanxt = areabot;
}
char *
getcell(nbytes)
unsigned nbytes;
{
register int nregio;
register struct region *p, *q;
register i;
if (nbytes == 0)
abort(); /* silly and defeats the algorithm */
/*
* round upwards and add administration area
*/
nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1;
for (p = areanxt;;) {
if (p->area > areanum) {
/*
* merge free cells
*/
while ((q = p->next)->area > areanum && q != areanxt)
p->next = q->next;
/*
* exit loop if cell big enough
*/
if (q >= p + nregio)
goto found;
}
p = p->next;
if (p == areanxt)
break;
}
i = nregio >= GROWBY ? nregio : GROWBY;
p = (struct region *)sbrk(i * REGSIZE);
if (p == (struct region *)-1)
return((char *)NULL);
p--;
if (p != areatop)
abort(); /* allocated areas are contiguous */
q = p + i;
p->next = q;
p->area = FREE;
q->next = areabot;
q->area = BUSY;
areatop = q;
found:
/*
* we found a FREE area big enough, pointed to by 'p', and up to 'q'
*/
areanxt = p + nregio;
if (areanxt < q) {
/*
* split into requested area and rest
*/
if (areanxt+1 > q)
abort(); /* insufficient space left for admin */
areanxt->next = q;
areanxt->area = FREE;
p->next = areanxt;
}
p->area = areanum;
return((char *)(p+1));
}
void
freecell(cp)
char *cp;
{
register struct region *p;
if ((p = (struct region *)cp) != NULL) {
p--;
if (p < areanxt)
areanxt = p;
p->area = FREE;
}
}
void
freearea(a)
register int a;
{
register struct region *p, *top;
top = areatop;
for (p = areabot; p != top; p = p->next)
if (p->area >= a)
p->area = FREE;
}
void
setarea(cp,a)
char *cp;
int a;
{
register struct region *p;
if ((p = (struct region *)cp) != NULL)
(p-1)->area = a;
}
int
getarea(cp)
char *cp;
{
return ((struct region*)cp-1)->area;
}
void
garbage()
{
register struct region *p, *q, *top;
top = areatop;
for (p = areabot; p != top; p = p->next) {
if (p->area > areanum) {
while ((q = p->next)->area > areanum)
p->next = q->next;
areanxt = p;
}
}
#ifdef SHRINKBY
if (areatop >= q + SHRINKBY && q->area > areanum) {
brk((char *)(q+1));
q->next = areabot;
q->area = BUSY;
areatop = q;
}
#endif
}

View file

@ -1,801 +0,0 @@
#define Extern extern
#include <sys/types.h>
#include <signal.h>
#define _NSIG NSIG
#include <errno.h>
#include <setjmp.h>
#include "sh.h"
/* -------- csyn.c -------- */
/*
* shell: syntax (C version)
*/
typedef union {
char *cp;
char **wp;
int i;
struct op *o;
} YYSTYPE;
#define WORD 256
#define LOGAND 257
#define LOGOR 258
#define BREAK 259
#define IF 260
#define THEN 261
#define ELSE 262
#define ELIF 263
#define FI 264
#define CASE 265
#define ESAC 266
#define FOR 267
#define WHILE 268
#define UNTIL 269
#define DO 270
#define DONE 271
#define IN 272
#define YYERRCODE 300
/* flags to yylex */
#define CONTIN 01 /* skip new lines to complete command */
/* #include "sh.h" */
#define SYNTAXERR zzerr()
static int startl;
static int peeksym;
static int nlseen;
static int iounit = IODEFAULT;
static YYSTYPE yylval;
_PROTOTYPE(static struct op *pipeline, (int cf ));
_PROTOTYPE(static struct op *andor, (void));
_PROTOTYPE(static struct op *c_list, (void));
_PROTOTYPE(static int synio, (int cf ));
_PROTOTYPE(static void musthave, (int c, int cf ));
_PROTOTYPE(static struct op *simple, (void));
_PROTOTYPE(static struct op *nested, (int type, int mark ));
_PROTOTYPE(static struct op *command, (int cf ));
_PROTOTYPE(static struct op *dogroup, (int onlydone ));
_PROTOTYPE(static struct op *thenpart, (void));
_PROTOTYPE(static struct op *elsepart, (void));
_PROTOTYPE(static struct op *caselist, (void));
_PROTOTYPE(static struct op *casepart, (void));
_PROTOTYPE(static char **pattern, (void));
_PROTOTYPE(static char **wordlist, (void));
_PROTOTYPE(static struct op *list, (struct op *t1, struct op *t2 ));
_PROTOTYPE(static struct op *block, (int type, struct op *t1, struct op *t2, char **wp ));
_PROTOTYPE(static struct op *newtp, (void));
_PROTOTYPE(static struct op *namelist, (struct op *t ));
_PROTOTYPE(static char **copyw, (void));
_PROTOTYPE(static void word, (char *cp ));
_PROTOTYPE(static struct ioword **copyio, (void));
_PROTOTYPE(static struct ioword *io, (int u, int f, char *cp ));
_PROTOTYPE(static void zzerr, (void));
_PROTOTYPE(void yyerror, (char *s ));
_PROTOTYPE(static int yylex, (int cf ));
_PROTOTYPE(int collect, (int c, int c1 ));
_PROTOTYPE(int dual, (int c ));
_PROTOTYPE(static void diag, (int ec ));
_PROTOTYPE(static char *tree, (unsigned size ));
_PROTOTYPE(void printf, (char *s ));
int
yyparse()
{
startl = 1;
peeksym = 0;
yynerrs = 0;
outtree = c_list();
musthave('\n', 0);
return(yynerrs!=0);
}
static struct op *
pipeline(cf)
int cf;
{
register struct op *t, *p;
register int c;
t = command(cf);
if (t != NULL) {
while ((c = yylex(0)) == '|') {
if ((p = command(CONTIN)) == NULL)
SYNTAXERR;
if (t->type != TPAREN && t->type != TCOM) {
/* shell statement */
t = block(TPAREN, t, NOBLOCK, NOWORDS);
}
t = block(TPIPE, t, p, NOWORDS);
}
peeksym = c;
}
return(t);
}
static struct op *
andor()
{
register struct op *t, *p;
register int c;
t = pipeline(0);
if (t != NULL) {
while ((c = yylex(0)) == LOGAND || c == LOGOR) {
if ((p = pipeline(CONTIN)) == NULL)
SYNTAXERR;
t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
}
peeksym = c;
}
return(t);
}
static struct op *
c_list()
{
register struct op *t, *p;
register int c;
t = andor();
if (t != NULL) {
if((peeksym = yylex(0)) == '&')
t = block(TASYNC, t, NOBLOCK, NOWORDS);
while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) {
if ((p = andor()) == NULL)
return(t);
if((peeksym = yylex(0)) == '&')
p = block(TASYNC, p, NOBLOCK, NOWORDS);
t = list(t, p);
}
peeksym = c;
}
return(t);
}
static int
synio(cf)
int cf;
{
register struct ioword *iop;
register int i;
register int c;
if ((c = yylex(cf)) != '<' && c != '>') {
peeksym = c;
return(0);
}
i = yylval.i;
musthave(WORD, 0);
iop = io(iounit, i, yylval.cp);
iounit = IODEFAULT;
if (i & IOHERE)
markhere(yylval.cp, iop);
return(1);
}
static void
musthave(c, cf)
int c, cf;
{
if ((peeksym = yylex(cf)) != c)
SYNTAXERR;
peeksym = 0;
}
static struct op *
simple()
{
register struct op *t;
t = NULL;
for (;;) {
switch (peeksym = yylex(0)) {
case '<':
case '>':
(void) synio(0);
break;
case WORD:
if (t == NULL) {
t = newtp();
t->type = TCOM;
}
peeksym = 0;
word(yylval.cp);
break;
default:
return(t);
}
}
}
static struct op *
nested(type, mark)
int type, mark;
{
register struct op *t;
multiline++;
t = c_list();
musthave(mark, 0);
multiline--;
return(block(type, t, NOBLOCK, NOWORDS));
}
static struct op *
command(cf)
int cf;
{
register struct op *t;
struct wdblock *iosave;
register int c;
iosave = iolist;
iolist = NULL;
if (multiline)
cf |= CONTIN;
while (synio(cf))
cf = 0;
switch (c = yylex(cf)) {
default:
peeksym = c;
if ((t = simple()) == NULL) {
if (iolist == NULL)
return((struct op *)NULL);
t = newtp();
t->type = TCOM;
}
break;
case '(':
t = nested(TPAREN, ')');
break;
case '{':
t = nested(TBRACE, '}');
break;
case FOR:
t = newtp();
t->type = TFOR;
musthave(WORD, 0);
startl = 1;
t->str = yylval.cp;
multiline++;
t->words = wordlist();
if ((c = yylex(0)) != '\n' && c != ';')
peeksym = c;
t->left = dogroup(0);
multiline--;
break;
case WHILE:
case UNTIL:
multiline++;
t = newtp();
t->type = c == WHILE? TWHILE: TUNTIL;
t->left = c_list();
t->right = dogroup(1);
t->words = NULL;
multiline--;
break;
case CASE:
t = newtp();
t->type = TCASE;
musthave(WORD, 0);
t->str = yylval.cp;
startl++;
multiline++;
musthave(IN, CONTIN);
startl++;
t->left = caselist();
musthave(ESAC, 0);
multiline--;
break;
case IF:
multiline++;
t = newtp();
t->type = TIF;
t->left = c_list();
t->right = thenpart();
musthave(FI, 0);
multiline--;
break;
}
while (synio(0))
;
t = namelist(t);
iolist = iosave;
return(t);
}
static struct op *
dogroup(onlydone)
int onlydone;
{
register int c;
register struct op *list;
c = yylex(CONTIN);
if (c == DONE && onlydone)
return((struct op *)NULL);
if (c != DO)
SYNTAXERR;
list = c_list();
musthave(DONE, 0);
return(list);
}
static struct op *
thenpart()
{
register int c;
register struct op *t;
if ((c = yylex(0)) != THEN) {
peeksym = c;
return((struct op *)NULL);
}
t = newtp();
t->type = 0;
t->left = c_list();
if (t->left == NULL)
SYNTAXERR;
t->right = elsepart();
return(t);
}
static struct op *
elsepart()
{
register int c;
register struct op *t;
switch (c = yylex(0)) {
case ELSE:
if ((t = c_list()) == NULL)
SYNTAXERR;
return(t);
case ELIF:
t = newtp();
t->type = TELIF;
t->left = c_list();
t->right = thenpart();
return(t);
default:
peeksym = c;
return((struct op *)NULL);
}
}
static struct op *
caselist()
{
register struct op *t;
t = NULL;
while ((peeksym = yylex(CONTIN)) != ESAC)
t = list(t, casepart());
return(t);
}
static struct op *
casepart()
{
register struct op *t;
t = newtp();
t->type = TPAT;
t->words = pattern();
musthave(')', 0);
t->left = c_list();
if ((peeksym = yylex(CONTIN)) != ESAC)
musthave(BREAK, CONTIN);
return(t);
}
static char **
pattern()
{
register int c, cf;
cf = CONTIN;
do {
musthave(WORD, cf);
word(yylval.cp);
cf = 0;
} while ((c = yylex(0)) == '|');
peeksym = c;
word(NOWORD);
return(copyw());
}
static char **
wordlist()
{
register int c;
if ((c = yylex(0)) != IN) {
peeksym = c;
return((char **)NULL);
}
startl = 0;
while ((c = yylex(0)) == WORD)
word(yylval.cp);
word(NOWORD);
peeksym = c;
return(copyw());
}
/*
* supporting functions
*/
static struct op *
list(t1, t2)
register struct op *t1, *t2;
{
if (t1 == NULL)
return(t2);
if (t2 == NULL)
return(t1);
return(block(TLIST, t1, t2, NOWORDS));
}
static struct op *
block(type, t1, t2, wp)
int type;
struct op *t1, *t2;
char **wp;
{
register struct op *t;
t = newtp();
t->type = type;
t->left = t1;
t->right = t2;
t->words = wp;
return(t);
}
struct res {
char *r_name;
int r_val;
} restab[] = {
"for", FOR,
"case", CASE,
"esac", ESAC,
"while", WHILE,
"do", DO,
"done", DONE,
"if", IF,
"in", IN,
"then", THEN,
"else", ELSE,
"elif", ELIF,
"until", UNTIL,
"fi", FI,
";;", BREAK,
"||", LOGOR,
"&&", LOGAND,
"{", '{',
"}", '}',
0,
};
int
rlookup(n)
register char *n;
{
register struct res *rp;
for (rp = restab; rp->r_name; rp++)
if (strcmp(rp->r_name, n) == 0)
return(rp->r_val);
return(0);
}
static struct op *
newtp()
{
register struct op *t;
t = (struct op *)tree(sizeof(*t));
t->type = 0;
t->words = NULL;
t->ioact = NULL;
t->left = NULL;
t->right = NULL;
t->str = NULL;
return(t);
}
static struct op *
namelist(t)
register struct op *t;
{
if (iolist) {
iolist = addword((char *)NULL, iolist);
t->ioact = copyio();
} else
t->ioact = NULL;
if (t->type != TCOM) {
if (t->type != TPAREN && t->ioact != NULL) {
t = block(TPAREN, t, NOBLOCK, NOWORDS);
t->ioact = t->left->ioact;
t->left->ioact = NULL;
}
return(t);
}
word(NOWORD);
t->words = copyw();
return(t);
}
static char **
copyw()
{
register char **wd;
wd = getwords(wdlist);
wdlist = 0;
return(wd);
}
static void
word(cp)
char *cp;
{
wdlist = addword(cp, wdlist);
}
static struct ioword **
copyio()
{
register struct ioword **iop;
iop = (struct ioword **) getwords(iolist);
iolist = 0;
return(iop);
}
static struct ioword *
io(u, f, cp)
int u;
int f;
char *cp;
{
register struct ioword *iop;
iop = (struct ioword *) tree(sizeof(*iop));
iop->io_unit = u;
iop->io_flag = f;
iop->io_name = cp;
iolist = addword((char *)iop, iolist);
return(iop);
}
static void
zzerr()
{
yyerror("syntax error");
}
void
yyerror(s)
char *s;
{
yynerrs++;
if (talking && e.iop <= iostack) {
multiline = 0;
while (eofc() == 0 && yylex(0) != '\n')
;
}
err(s);
fail();
}
static int
yylex(cf)
int cf;
{
register int c, c1;
int atstart;
if ((c = peeksym) > 0) {
peeksym = 0;
if (c == '\n')
startl = 1;
return(c);
}
nlseen = 0;
e.linep = line;
atstart = startl;
startl = 0;
yylval.i = 0;
loop:
while ((c = getc(0)) == ' ' || c == '\t')
;
switch (c) {
default:
if (any(c, "0123456789")) {
unget(c1 = getc(0));
if (c1 == '<' || c1 == '>') {
iounit = c - '0';
goto loop;
}
*e.linep++ = c;
c = c1;
}
break;
case '#':
while ((c = getc(0)) != 0 && c != '\n')
;
unget(c);
goto loop;
case 0:
return(c);
case '$':
*e.linep++ = c;
if ((c = getc(0)) == '{') {
if ((c = collect(c, '}')) != '\0')
return(c);
goto pack;
}
break;
case '`':
case '\'':
case '"':
if ((c = collect(c, c)) != '\0')
return(c);
goto pack;
case '|':
case '&':
case ';':
if ((c1 = dual(c)) != '\0') {
startl = 1;
return(c1);
}
startl = 1;
return(c);
case '^':
startl = 1;
return('|');
case '>':
case '<':
diag(c);
return(c);
case '\n':
nlseen++;
gethere();
startl = 1;
if (multiline || cf & CONTIN) {
if (talking && e.iop <= iostack)
prs(cprompt->value);
if (cf & CONTIN)
goto loop;
}
return(c);
case '(':
case ')':
startl = 1;
return(c);
}
unget(c);
pack:
while ((c = getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n"))
if (e.linep >= elinep)
err("word too long");
else
*e.linep++ = c;
unget(c);
if(any(c, "\"'`$"))
goto loop;
*e.linep++ = '\0';
if (atstart && (c = rlookup(line))!=0) {
startl = 1;
return(c);
}
yylval.cp = strsave(line, areanum);
return(WORD);
}
int
collect(c, c1)
register c, c1;
{
char s[2];
*e.linep++ = c;
while ((c = getc(c1)) != c1) {
if (c == 0) {
unget(c);
s[0] = c1;
s[1] = 0;
prs("no closing "); yyerror(s);
return(YYERRCODE);
}
if (talking && c == '\n' && e.iop <= iostack)
prs(cprompt->value);
*e.linep++ = c;
}
*e.linep++ = c;
return(0);
}
int
dual(c)
register c;
{
char s[3];
register char *cp = s;
*cp++ = c;
*cp++ = getc(0);
*cp = 0;
if ((c = rlookup(s)) == 0)
unget(*--cp);
return(c);
}
static void
diag(ec)
register int ec;
{
register int c;
c = getc(0);
if (c == '>' || c == '<') {
if (c != ec)
zzerr();
yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE;
c = getc(0);
} else
yylval.i = ec == '>'? IOWRITE: IOREAD;
if (c != '&' || yylval.i == IOHERE)
unget(c);
else
yylval.i |= IODUP;
}
static char *
tree(size)
unsigned size;
{
register char *t;
if ((t = getcell(size)) == NULL) {
prs("command line too complicated\n");
fail();
/* NOTREACHED */
}
return(t);
}
/* VARARGS1 */
/* ARGSUSED */
void
printf(s) /* yyparse calls it */
char *s;
{
}

File diff suppressed because it is too large Load diff

View file

@ -1,767 +0,0 @@
#define Extern extern
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <limits.h>
#include <signal.h>
#define _NSIG NSIG
#include <errno.h>
#include <setjmp.h>
#include "sh.h"
/* -------- eval.c -------- */
/* #include "sh.h" */
/* #include "word.h" */
/*
* ${}
* `command`
* blank interpretation
* quoting
* glob
*/
_PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f ));
_PROTOTYPE(static char *blank, (int f ));
_PROTOTYPE(static int dollar, (int quoted ));
_PROTOTYPE(static int grave, (int quoted ));
_PROTOTYPE(void globname, (char *we, char *pp ));
_PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end ));
_PROTOTYPE(static int anyspcl, (struct wdblock *wb ));
_PROTOTYPE(static int xstrcmp, (char *p1, char *p2 ));
_PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *)));
_PROTOTYPE(void glob1, (char *base, char *lim ));
_PROTOTYPE(void glob2, (char *i, char *j ));
_PROTOTYPE(void glob3, (char *i, char *j, char *k ));
_PROTOTYPE(char *memcopy, (char *ato, char *from, int nb ));
char **
eval(ap, f)
register char **ap;
int f;
{
struct wdblock *wb;
char **wp;
char **wf;
jmp_buf ev;
wp = NULL;
wb = NULL;
wf = NULL;
if (newenv(setjmp(errpt = ev)) == 0) {
while (*ap && isassign(*ap))
expand(*ap++, &wb, f & ~DOGLOB);
if (flag['k']) {
for (wf = ap; *wf; wf++) {
if (isassign(*wf))
expand(*wf, &wb, f & ~DOGLOB);
}
}
for (wb = addword((char *)0, wb); *ap; ap++) {
if (!flag['k'] || !isassign(*ap))
expand(*ap, &wb, f & ~DOKEY);
}
wb = addword((char *)0, wb);
wp = getwords(wb);
quitenv();
} else
gflg = 1;
return(gflg? (char **)NULL: wp);
}
/*
* Make the exported environment from the exported
* names in the dictionary. Keyword assignments
* will already have been done.
*/
char **
makenv()
{
register struct wdblock *wb;
register struct var *vp;
wb = NULL;
for (vp = vlist; vp; vp = vp->next)
if (vp->status & EXPORT)
wb = addword(vp->name, wb);
wb = addword((char *)0, wb);
return(getwords(wb));
}
char *
evalstr(cp, f)
register char *cp;
int f;
{
struct wdblock *wb;
wb = NULL;
if (expand(cp, &wb, f)) {
if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL)
cp = "";
DELETE(wb);
} else
cp = NULL;
return(cp);
}
static int
expand(cp, wbp, f)
register char *cp;
register struct wdblock **wbp;
int f;
{
jmp_buf ev;
gflg = 0;
if (cp == NULL)
return(0);
if (!anys("$`'\"", cp) &&
!anys(ifs->value, cp) &&
((f&DOGLOB)==0 || !anys("[*?", cp))) {
cp = strsave(cp, areanum);
if (f & DOTRIM)
unquote(cp);
*wbp = addword(cp, *wbp);
return(1);
}
if (newenv(setjmp(errpt = ev)) == 0) {
PUSHIO(aword, cp, strchar);
e.iobase = e.iop;
while ((cp = blank(f)) && gflg == 0) {
e.linep = cp;
cp = strsave(cp, areanum);
if ((f&DOGLOB) == 0) {
if (f & DOTRIM)
unquote(cp);
*wbp = addword(cp, *wbp);
} else
*wbp = glob(cp, *wbp);
}
quitenv();
} else
gflg = 1;
return(gflg == 0);
}
/*
* Blank interpretation and quoting
*/
static char *
blank(f)
int f;
{
register c, c1;
register char *sp;
int scanequals, foundequals;
sp = e.linep;
scanequals = f & DOKEY;
foundequals = 0;
loop:
switch (c = subgetc('"', foundequals)) {
case 0:
if (sp == e.linep)
return(0);
*e.linep++ = 0;
return(sp);
default:
if (f & DOBLANK && any(c, ifs->value))
goto loop;
break;
case '"':
case '\'':
scanequals = 0;
if (INSUB())
break;
for (c1 = c; (c = subgetc(c1, 1)) != c1;) {
if (c == 0)
break;
if (c == '\'' || !any(c, "$`\""))
c |= QUOTE;
*e.linep++ = c;
}
c = 0;
}
unget(c);
if (!letter(c))
scanequals = 0;
for (;;) {
c = subgetc('"', foundequals);
if (c == 0 ||
f & (DOBLANK && any(c, ifs->value)) ||
(!INSUB() && any(c, "\"'"))) {
scanequals = 0;
unget(c);
if (any(c, "\"'"))
goto loop;
break;
}
if (scanequals)
if (c == '=') {
foundequals = 1;
scanequals = 0;
}
else if (!letnum(c))
scanequals = 0;
*e.linep++ = c;
}
*e.linep++ = 0;
return(sp);
}
/*
* Get characters, substituting for ` and $
*/
int
subgetc(ec, quoted)
register char ec;
int quoted;
{
register char c;
again:
c = getc(ec);
if (!INSUB() && ec != '\'') {
if (c == '`') {
if (grave(quoted) == 0)
return(0);
e.iop->task = XGRAVE;
goto again;
}
if (c == '$' && (c = dollar(quoted)) == 0) {
e.iop->task = XDOLL;
goto again;
}
}
return(c);
}
/*
* Prepare to generate the string returned by ${} substitution.
*/
static int
dollar(quoted)
int quoted;
{
int otask;
struct io *oiop;
char *dolp;
register char *s, c, *cp;
struct var *vp;
c = readc();
s = e.linep;
if (c != '{') {
*e.linep++ = c;
if (letter(c)) {
while ((c = readc())!=0 && letnum(c))
if (e.linep < elinep)
*e.linep++ = c;
unget(c);
}
c = 0;
} else {
oiop = e.iop;
otask = e.iop->task;
e.iop->task = XOTHER;
while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n')
if (e.linep < elinep)
*e.linep++ = c;
if (oiop == e.iop)
e.iop->task = otask;
if (c != '}') {
err("unclosed ${");
gflg++;
return(c);
}
}
if (e.linep >= elinep) {
err("string in ${} too long");
gflg++;
e.linep -= 10;
}
*e.linep = 0;
if (*s)
for (cp = s+1; *cp; cp++)
if (any(*cp, "=-+?")) {
c = *cp;
*cp++ = 0;
break;
}
if (s[1] == 0 && (*s == '*' || *s == '@')) {
if (dolc > 1) {
/* currently this does not distinguish $* and $@ */
/* should check dollar */
e.linep = s;
PUSHIO(awordlist, dolv+1, dolchar);
return(0);
} else { /* trap the nasty ${=} */
s[0] = '1';
s[1] = 0;
}
}
vp = lookup(s);
if ((dolp = vp->value) == null) {
switch (c) {
case '=':
if (digit(*s)) {
err("cannot use ${...=...} with $n");
gflg++;
break;
}
setval(vp, cp);
dolp = vp->value;
break;
case '-':
dolp = strsave(cp, areanum);
break;
case '?':
if (*cp == 0) {
prs("missing value for ");
err(s);
} else
err(cp);
gflg++;
break;
}
} else if (c == '+')
dolp = strsave(cp, areanum);
if (flag['u'] && dolp == null) {
prs("unset variable: ");
err(s);
gflg++;
}
e.linep = s;
PUSHIO(aword, dolp, quoted ? qstrchar : strchar);
return(0);
}
/*
* Run the command in `...` and read its output.
*/
static int
grave(quoted)
int quoted;
{
register char *cp;
register int i;
int pf[2];
for (cp = e.iop->argp->aword; *cp != '`'; cp++)
if (*cp == 0) {
err("no closing `");
return(0);
}
if (openpipe(pf) < 0)
return(0);
if ((i = fork()) == -1) {
closepipe(pf);
err("try again");
return(0);
}
if (i != 0) {
e.iop->argp->aword = ++cp;
close(pf[1]);
PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar);
return(1);
}
*cp = 0;
/* allow trapped signals */
for (i=0; i<=_NSIG; i++)
if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN)
signal(i, SIG_DFL);
dup2(pf[1], 1);
closepipe(pf);
flag['e'] = 0;
flag['v'] = 0;
flag['n'] = 0;
cp = strsave(e.iop->argp->aword, 0);
areanum = 1;
freehere(areanum);
freearea(areanum); /* free old space */
e.oenv = NULL;
e.iop = (e.iobase = iostack) - 1;
unquote(cp);
talking = 0;
PUSHIO(aword, cp, nlchar);
onecommand();
exit(1);
}
char *
unquote(as)
register char *as;
{
register char *s;
if ((s = as) != NULL)
while (*s)
*s++ &= ~QUOTE;
return(as);
}
/* -------- glob.c -------- */
/* #include "sh.h" */
/*
* glob
*/
#define scopy(x) strsave((x), areanum)
#define BLKSIZ 512
#define NDENT ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent))
static struct wdblock *cl, *nl;
static char spcl[] = "[?*";
struct wdblock *
glob(cp, wb)
char *cp;
struct wdblock *wb;
{
register i;
register char *pp;
if (cp == 0)
return(wb);
i = 0;
for (pp = cp; *pp; pp++)
if (any(*pp, spcl))
i++;
else if (!any(*pp & ~QUOTE, spcl))
*pp &= ~QUOTE;
if (i != 0) {
for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) {
nl = newword(cl->w_nword*2);
for(i=0; i<cl->w_nword; i++) { /* for each argument */
for (pp = cl->w_words[i]; *pp; pp++)
if (any(*pp, spcl)) {
globname(cl->w_words[i], pp);
break;
}
if (*pp == '\0')
nl = addword(scopy(cl->w_words[i]), nl);
}
for(i=0; i<cl->w_nword; i++)
DELETE(cl->w_words[i]);
DELETE(cl);
}
for(i=0; i<cl->w_nword; i++)
unquote(cl->w_words[i]);
glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp);
if (cl->w_nword) {
for (i=0; i<cl->w_nword; i++)
wb = addword(cl->w_words[i], wb);
DELETE(cl);
return(wb);
}
}
wb = addword(unquote(cp), wb);
return(wb);
}
void
globname(we, pp)
char *we;
register char *pp;
{
register char *np, *cp;
char *name, *gp, *dp;
int dn, j, n, k;
DIR *dirp;
struct dirent *de;
char dname[NAME_MAX+1];
struct stat dbuf;
for (np = we; np != pp; pp--)
if (pp[-1] == '/')
break;
for (dp = cp = space((int)(pp-np)+3); np < pp;)
*cp++ = *np++;
*cp++ = '.';
*cp = '\0';
for (gp = cp = space(strlen(pp)+1); *np && *np != '/';)
*cp++ = *np++;
*cp = '\0';
dirp = opendir(dp);
if (dirp == 0) {
DELETE(dp);
DELETE(gp);
return;
}
dname[NAME_MAX] = '\0';
while ((de=readdir(dirp))!=NULL) {
/* XXX Hmmm... What this could be? (abial) */
/*
if (ent[j].d_ino == 0)
continue;
*/
strncpy(dname, de->d_name, NAME_MAX);
if (dname[0] == '.')
if (*gp != '.')
continue;
for(k=0; k<NAME_MAX; k++)
if (any(dname[k], spcl))
dname[k] |= QUOTE;
if (gmatch(dname, gp)) {
name = generate(we, pp, dname, np);
if (*np && !anys(np, spcl)) {
if (stat(name,&dbuf)) {
DELETE(name);
continue;
}
}
nl = addword(name, nl);
}
}
closedir(dirp);
DELETE(dp);
DELETE(gp);
}
/*
* generate a pathname as below.
* start..end1 / middle end
* the slashes come for free
*/
static char *
generate(start1, end1, middle, end)
char *start1;
register char *end1;
char *middle, *end;
{
char *p;
register char *op, *xp;
p = op = space((int)(end1-start1)+strlen(middle)+strlen(end)+2);
for (xp = start1; xp != end1;)
*op++ = *xp++;
for (xp = middle; (*op++ = *xp++) != '\0';)
;
op--;
for (xp = end; (*op++ = *xp++) != '\0';)
;
return(p);
}
static int
anyspcl(wb)
register struct wdblock *wb;
{
register i;
register char **wd;
wd = wb->w_words;
for (i=0; i<wb->w_nword; i++)
if (anys(spcl, *wd++))
return(1);
return(0);
}
static int
xstrcmp(p1, p2)
char *p1, *p2;
{
return(strcmp(*(char **)p1, *(char **)p2));
}
/* -------- word.c -------- */
/* #include "sh.h" */
/* #include "word.h" */
#define NSTART 16 /* default number of words to allow for initially */
struct wdblock *
newword(nw)
register int nw;
{
register struct wdblock *wb;
wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *));
wb->w_bsize = nw;
wb->w_nword = 0;
return(wb);
}
struct wdblock *
addword(wd, wb)
char *wd;
register struct wdblock *wb;
{
register struct wdblock *wb2;
register nw;
if (wb == NULL)
wb = newword(NSTART);
if ((nw = wb->w_nword) >= wb->w_bsize) {
wb2 = newword(nw * 2);
memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *));
wb2->w_nword = nw;
DELETE(wb);
wb = wb2;
}
wb->w_words[wb->w_nword++] = wd;
return(wb);
}
char **
getwords(wb)
register struct wdblock *wb;
{
register char **wd;
register nb;
if (wb == NULL)
return((char **)NULL);
if (wb->w_nword == 0) {
DELETE(wb);
return((char **)NULL);
}
wd = (char **) space(nb = sizeof(*wd) * wb->w_nword);
memcopy((char *)wd, (char *)wb->w_words, nb);
DELETE(wb); /* perhaps should done by caller */
return(wd);
}
_PROTOTYPE(int (*func), (char *, char *));
int globv;
void
glob0(a0, a1, a2, a3)
char *a0;
unsigned a1;
int a2;
_PROTOTYPE(int (*a3), (char *, char *));
{
func = a3;
globv = a2;
glob1(a0, a0 + a1 * a2);
}
void
glob1(base, lim)
char *base, *lim;
{
register char *i, *j;
int v2;
char *lptr, *hptr;
int c;
unsigned n;
v2 = globv;
top:
if ((n=(int)(lim-base)) <= v2)
return;
n = v2 * (n / (2*v2));
hptr = lptr = base+n;
i = base;
j = lim-v2;
for(;;) {
if (i < lptr) {
if ((c = (*func)(i, lptr)) == 0) {
glob2(i, lptr -= v2);
continue;
}
if (c < 0) {
i += v2;
continue;
}
}
begin:
if (j > hptr) {
if ((c = (*func)(hptr, j)) == 0) {
glob2(hptr += v2, j);
goto begin;
}
if (c > 0) {
if (i == lptr) {
glob3(i, hptr += v2, j);
i = lptr += v2;
goto begin;
}
glob2(i, j);
j -= v2;
i += v2;
continue;
}
j -= v2;
goto begin;
}
if (i == lptr) {
if (lptr-base >= lim-hptr) {
glob1(hptr+v2, lim);
lim = lptr;
} else {
glob1(base, lptr);
base = hptr+v2;
}
goto top;
}
glob3(j, lptr -= v2, i);
j = hptr -= v2;
}
}
void
glob2(i, j)
char *i, *j;
{
register char *index1, *index2, c;
int m;
m = globv;
index1 = i;
index2 = j;
do {
c = *index1;
*index1++ = *index2;
*index2++ = c;
} while(--m);
}
void
glob3(i, j, k)
char *i, *j, *k;
{
register char *index1, *index2, *index3;
int c;
int m;
m = globv;
index1 = i;
index2 = j;
index3 = k;
do {
c = *index1;
*index1++ = *index3;
*index3++ = *index2;
*index2++ = c;
} while(--m);
}
char *
memcopy(ato, from, nb)
register char *ato, *from;
register int nb;
{
register char *to;
to = ato;
while (--nb >= 0)
*to++ = *from++;
return(ato);
}

View file

@ -1,675 +0,0 @@
#define Extern extern
#include <sys/types.h>
#include <signal.h>
#define _NSIG NSIG
#include <errno.h>
#include <setjmp.h>
#include "sh.h"
/* -------- io.c -------- */
/* #include "sh.h" */
/*
* shell IO
*/
static struct iobuf sharedbuf = {AFID_NOBUF};
static struct iobuf mainbuf = {AFID_NOBUF};
static unsigned bufid = AFID_ID; /* buffer id counter */
struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0};
_PROTOTYPE(static void readhere, (char **name, char *s, int ec ));
_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)()));
_PROTOTYPE(static int xxchar, (struct ioarg *ap ));
_PROTOTYPE(void tempname, (char *tname ));
int
getc(ec)
register int ec;
{
register int c;
if(e.linep > elinep) {
while((c=readc()) != '\n' && c)
;
err("input line too long");
gflg++;
return(c);
}
c = readc();
if (ec != '\'' && e.iop->task != XGRAVE) {
if(c == '\\') {
c = readc();
if (c == '\n' && ec != '\"')
return(getc(ec));
c |= QUOTE;
}
}
return(c);
}
void
unget(c)
int c;
{
if (e.iop >= e.iobase)
e.iop->peekc = c;
}
int
eofc()
{
return e.iop < e.iobase || (e.iop->peekc == 0 && e.iop->prev == 0);
}
int
readc()
{
register c;
for (; e.iop >= e.iobase; e.iop--)
if ((c = e.iop->peekc) != '\0') {
e.iop->peekc = 0;
return(c);
}
else {
if (e.iop->prev != 0) {
if ((c = (*e.iop->iofn)(e.iop->argp, e.iop)) != '\0') {
if (c == -1) {
e.iop++;
continue;
}
if (e.iop == iostack)
ioecho(c);
return(e.iop->prev = c);
}
else if (e.iop->task == XIO && e.iop->prev != '\n') {
e.iop->prev = 0;
if (e.iop == iostack)
ioecho('\n');
return '\n';
}
}
if (e.iop->task == XIO) {
if (multiline)
return e.iop->prev = 0;
if (talking && e.iop == iostack+1)
prs(prompt->value);
}
}
if (e.iop >= iostack)
return(0);
leave();
/* NOTREACHED */
}
void
ioecho(c)
char c;
{
if (flag['v'])
write(2, &c, sizeof c);
}
void
pushio(argp, fn)
struct ioarg *argp;
int (*fn)();
{
if (++e.iop >= &iostack[NPUSH]) {
e.iop--;
err("Shell input nested too deeply");
gflg++;
return;
}
e.iop->iofn = fn;
if (argp->afid != AFID_NOBUF)
e.iop->argp = argp;
else {
e.iop->argp = ioargstack + (e.iop - iostack);
*e.iop->argp = *argp;
e.iop->argp->afbuf = e.iop == &iostack[0] ? &mainbuf : &sharedbuf;
if (isatty(e.iop->argp->afile) == 0 &&
(e.iop == &iostack[0] ||
lseek(e.iop->argp->afile, 0L, 1) != -1)) {
if (++bufid == AFID_NOBUF)
bufid = AFID_ID;
e.iop->argp->afid = bufid;
}
}
e.iop->prev = ~'\n';
e.iop->peekc = 0;
e.iop->xchar = 0;
e.iop->nlcount = 0;
if (fn == filechar || fn == linechar)
e.iop->task = XIO;
else if (fn == gravechar || fn == qgravechar)
e.iop->task = XGRAVE;
else
e.iop->task = XOTHER;
}
struct io *
setbase(ip)
struct io *ip;
{
register struct io *xp;
xp = e.iobase;
e.iobase = ip;
return(xp);
}
/*
* Input generating functions
*/
/*
* Produce the characters of a string, then a newline, then EOF.
*/
int
nlchar(ap)
register struct ioarg *ap;
{
register int c;
if (ap->aword == NULL)
return(0);
if ((c = *ap->aword++) == 0) {
ap->aword = NULL;
return('\n');
}
return(c);
}
/*
* Given a list of words, produce the characters
* in them, with a space after each word.
*/
int
wdchar(ap)
register struct ioarg *ap;
{
register char c;
register char **wl;
if ((wl = ap->awordlist) == NULL)
return(0);
if (*wl != NULL) {
if ((c = *(*wl)++) != 0)
return(c & 0177);
ap->awordlist++;
return(' ');
}
ap->awordlist = NULL;
return('\n');
}
/*
* Return the characters of a list of words,
* producing a space between them.
*/
int
dolchar(ap)
register struct ioarg *ap;
{
register char *wp;
if ((wp = *ap->awordlist++) != NULL) {
PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar);
return(-1);
}
return(0);
}
static int
xxchar(ap)
register struct ioarg *ap;
{
register int c;
if (ap->aword == NULL)
return(0);
if ((c = *ap->aword++) == '\0') {
ap->aword = NULL;
return(' ');
}
return(c);
}
/*
* Produce the characters from a single word (string).
*/
int
strchar(ap)
register struct ioarg *ap;
{
register int c;
if (ap->aword == NULL || (c = *ap->aword++) == 0)
return(0);
return(c);
}
/*
* Produce quoted characters from a single word (string).
*/
int
qstrchar(ap)
register struct ioarg *ap;
{
register int c;
if (ap->aword == NULL || (c = *ap->aword++) == 0)
return(0);
return(c|QUOTE);
}
/*
* Return the characters from a file.
*/
int
filechar(ap)
register struct ioarg *ap;
{
register int i;
char c;
struct iobuf *bp = ap->afbuf;
if (ap->afid != AFID_NOBUF) {
if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) {
if (i)
lseek(ap->afile, ap->afpos, 0);
do {
i = read(ap->afile, bp->buf, sizeof(bp->buf));
} while (i < 0 && errno == EINTR);
if (i <= 0) {
closef(ap->afile);
return 0;
}
bp->id = ap->afid;
bp->ebufp = (bp->bufp = bp->buf) + i;
}
ap->afpos++;
return *bp->bufp++ & 0177;
}
do {
i = read(ap->afile, &c, sizeof(c));
} while (i < 0 && errno == EINTR);
return(i == sizeof(c)? c&0177: (closef(ap->afile), 0));
}
/*
* Return the characters from a here temp file.
*/
int
herechar(ap)
register struct ioarg *ap;
{
char c;
if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) {
close(ap->afile);
c = 0;
}
return (c);
}
/*
* Return the characters produced by a process (`...`).
* Quote them if required, and remove any trailing newline characters.
*/
int
gravechar(ap, iop)
struct ioarg *ap;
struct io *iop;
{
register int c;
if ((c = qgravechar(ap, iop)&~QUOTE) == '\n')
c = ' ';
return(c);
}
int
qgravechar(ap, iop)
register struct ioarg *ap;
struct io *iop;
{
register int c;
if (iop->xchar) {
if (iop->nlcount) {
iop->nlcount--;
return('\n'|QUOTE);
}
c = iop->xchar;
iop->xchar = 0;
} else if ((c = filechar(ap)) == '\n') {
iop->nlcount = 1;
while ((c = filechar(ap)) == '\n')
iop->nlcount++;
iop->xchar = c;
if (c == 0)
return(c);
iop->nlcount--;
c = '\n';
}
return(c!=0? c|QUOTE: 0);
}
/*
* Return a single command (usually the first line) from a file.
*/
int
linechar(ap)
register struct ioarg *ap;
{
register int c;
if ((c = filechar(ap)) == '\n') {
if (!multiline) {
closef(ap->afile);
ap->afile = -1; /* illegal value */
}
}
return(c);
}
void
prs(s)
register char *s;
{
if (*s)
write(2, s, strlen(s));
}
void
putc(c)
char c;
{
write(2, &c, sizeof c);
}
void
prn(u)
unsigned u;
{
prs(itoa(u, 0));
}
void
closef(i)
register int i;
{
if (i > 2)
close(i);
}
void
closeall()
{
register u;
for (u=NUFILE; u<NOFILE;)
close(u++);
}
/*
* remap fd into Shell's fd space
*/
int
remap(fd)
register int fd;
{
register int i;
int map[NOFILE];
if (fd < e.iofd) {
for (i=0; i<NOFILE; i++)
map[i] = 0;
do {
map[fd] = 1;
fd = dup(fd);
} while (fd >= 0 && fd < e.iofd);
for (i=0; i<NOFILE; i++)
if (map[i])
close(i);
if (fd < 0)
err("too many files open in shell");
}
return(fd);
}
int
openpipe(pv)
register int *pv;
{
register int i;
if ((i = pipe(pv)) < 0)
err("can't create pipe - try again");
return(i);
}
void
closepipe(pv)
register int *pv;
{
if (pv != NULL) {
close(*pv++);
close(*pv);
}
}
/* -------- here.c -------- */
/* #include "sh.h" */
/*
* here documents
*/
struct here {
char *h_tag;
int h_dosub;
struct ioword *h_iop;
struct here *h_next;
};
static struct here *inhere; /* list of hear docs while parsing */
static struct here *acthere; /* list of active here documents */
void
markhere(s, iop)
register char *s;
struct ioword *iop;
{
register struct here *h, *lh;
h = (struct here *) space(sizeof(struct here));
if (h == 0)
return;
h->h_tag = evalstr(s, DOSUB);
if (h->h_tag == 0)
return;
h->h_iop = iop;
iop->io_name = 0;
h->h_next = NULL;
if (inhere == 0)
inhere = h;
else
for (lh = inhere; lh!=NULL; lh = lh->h_next)
if (lh->h_next == 0) {
lh->h_next = h;
break;
}
iop->io_flag |= IOHERE|IOXHERE;
for (s = h->h_tag; *s; s++)
if (*s & QUOTE) {
iop->io_flag &= ~ IOXHERE;
*s &= ~ QUOTE;
}
h->h_dosub = iop->io_flag & IOXHERE;
}
void
gethere()
{
register struct here *h, *hp;
/* Scan here files first leaving inhere list in place */
for (hp = h = inhere; h != NULL; hp = h, h = h->h_next)
readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\'');
/* Make inhere list active - keep list intact for scraphere */
if (hp != NULL) {
hp->h_next = acthere;
acthere = inhere;
inhere = NULL;
}
}
static void
readhere(name, s, ec)
char **name;
register char *s;
int ec;
{
int tf;
char tname[30];
register c;
jmp_buf ev;
char line [LINELIM+1];
char *next;
tempname(tname);
*name = strsave(tname, areanum);
tf = creat(tname, 0600);
if (tf < 0)
return;
if (newenv(setjmp(errpt = ev)) != 0)
unlink(tname);
else {
pushio(e.iop->argp, e.iop->iofn);
e.iobase = e.iop;
for (;;) {
if (talking && e.iop <= iostack)
prs(cprompt->value);
next = line;
while ((c = getc(ec)) != '\n' && c) {
if (ec == '\'')
c &= ~ QUOTE;
if (next >= &line[LINELIM]) {
c = 0;
break;
}
*next++ = c;
}
*next = 0;
if (strcmp(s, line) == 0 || c == 0)
break;
*next++ = '\n';
write (tf, line, (int)(next-line));
}
if (c == 0) {
prs("here document `"); prs(s); err("' unclosed");
}
quitenv();
}
close(tf);
}
/*
* open here temp file.
* if unquoted here, expand here temp file into second temp file.
*/
int
herein(hname, xdoll)
char *hname;
int xdoll;
{
register hf, tf;
if (hname == 0)
return(-1);
hf = open(hname, 0);
if (hf < 0)
return (-1);
if (xdoll) {
char c;
char tname[30];
jmp_buf ev;
tempname(tname);
if ((tf = creat(tname, 0600)) < 0)
return (-1);
if (newenv(setjmp(errpt = ev)) == 0) {
PUSHIO(afile, hf, herechar);
setbase(e.iop);
while ((c = subgetc(0, 0)) != 0) {
c &= ~ QUOTE;
write(tf, &c, sizeof c);
}
quitenv();
} else
unlink(tname);
close(tf);
tf = open(tname, 0);
unlink(tname);
return (tf);
} else
return (hf);
}
void
scraphere()
{
register struct here *h;
for (h = inhere; h != NULL; h = h->h_next) {
if (h->h_iop && h->h_iop->io_name)
unlink(h->h_iop->io_name);
}
inhere = NULL;
}
/* unlink here temp files before a freearea(area) */
void
freehere(area)
int area;
{
register struct here *h, *hl;
hl = NULL;
for (h = acthere; h != NULL; h = h->h_next)
if (getarea((char *) h) >= area) {
if (h->h_iop->io_name != NULL)
unlink(h->h_iop->io_name);
if (hl == NULL)
acthere = h->h_next;
else
hl->h_next = h->h_next;
} else
hl = h;
}
void
tempname(tname)
char *tname;
{
static int inc;
register char *cp, *lp;
for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++)
;
lp = putn(getpid()*1000 + inc++);
for (; (*cp = *lp++) != '\0'; cp++)
;
}

View file

@ -1,9 +0,0 @@
#define Extern
#include <sys/types.h>
#include <signal.h>
#define _NSIG NSIG
#include <errno.h>
#include <setjmp.h>
#include "sh.h"