This commit is contained in:
seta75D
2021-10-11 18:20:23 -03:00
commit 2e8a93c394
13448 changed files with 2891753 additions and 0 deletions

78
5bin/Makefile Normal file
View File

@@ -0,0 +1,78 @@
#
# @(#)Makefile 1.1 92/08/05 SMI
#
DESTDIR=
CFLAGS= -O
CC= /bin/cc
S5CC= /usr/5bin/cc
MAKE= make CC=${S5CC}
.KEEP_STATE:
# Programs that live in subdirectories, and have makefiles of their own.
#
SUBDIR= diff3 m4 sed
# Shell scripts that need only be installed and are never removed.
#
SCRIPT= ar dircmp
SCRIPTSRC= ar.sh dircmp.sh
# C programs that live in the current directory and do not need
# explicit make lines.
#
STD= banner cat du echo expr nohup pr sum time tr df ln
# Programs that must run setuid to root
#
SETUID= su
# C programs that live in the current directory and need explicit make lines.
#
NSTD= ls pg tabs
# C programs that live in the current directory but
# whose source is in /usr/src/usr.bin.
SHAREDUSRBIN= chmod col date grep od sort stty touch su
all: ${SUBDIR} ${STD} ${NSTD} ${SHAREDUSRBIN} ${SETUID}
${SUBDIR}: FRC
cd $@; ${MAKE} ${MFLAGS}
${STD}:
${S5CC} ${CFLAGS} -DS5EMUL -o $@ $@.c
${SHAREDUSRBIN}:
(if [ ! -f ../usr.bin/$@.c ]; then cd ../usr.bin;sccs get $@.c; fi;)
${CC} ${CFLAGS} -DS5EMUL -o $@ ../usr.bin/$@.c
install: ${STD} ${NSTD} ${SHAREDUSRBIN} ${SCRIPTSRC} ${SETUID}
install -d -o bin -m 755 ${DESTDIR}/usr/5bin
-for i in ${SUBDIR}; do \
(cd $$i; ${MAKE} ${MFLAGS} DESTDIR=${DESTDIR} install); done
-for i in ${SCRIPT}; do (install -c $$i.sh ${DESTDIR}/usr/5bin/$$i); done
-for i in ${STD} ${NSTD} ${SHAREDUSRBIN}; do \
(install -s $$i ${DESTDIR}/usr/5bin/$$i); \
done
install -s -m 4755 ${SETUID} ${DESTDIR}/usr/5bin
rm -f ${DESTDIR}/usr/5bin/cc; ln -s ../5lib/compile ${DESTDIR}/usr/5bin/cc
clean:
rm -f a.out y.tab.* core *.s *.o
for i in ${SUBDIR}; do (cd $$i; ${MAKE} ${MFLAGS} clean); done
rm -f ${STD} ${NSTD} ${SHAREDUSRBIN}
FRC:
# Files listed in ${NSTD} have explicit make lines given below.
ls: ls.c
${S5CC} -o ls ${CFLAGS} -DSINGLE -DS5EMUL ls.c -lcurses
pg: pg.c
${S5CC} -o pg ${CFLAGS} -DSINGLE -DS5EMUL pg.c -lcurses
tabs: tabs.c
${S5CC} -o tabs ${CFLAGS} -DS5EMUL tabs.c -lcurses

109
5bin/ar.sh Normal file
View File

@@ -0,0 +1,109 @@
#! /bin/sh -
#
# %Z%%M% %I% %E% SMI
#
#
# Paranoia. Set IFS to "<blank><tab><newline>". Set PATH to
# /bin:/usr/bin:/usr/ucb; this makes sure we don't run anything funny,
# and also makes sure that when we run "ar" we run the REAL "ar".
# We export it to make sure "ranlib" runs the REAL "ar" as well.
#
IFS="
"
PATH=/bin:/usr/bin:/usr/ucb
export PATH
#
# Initialize usage message.
#
usage="usage: ar [mrxtdpq][uvcnbailos] [posname] archive files ..."
#
# Check the number of arguments.
#
if [ $# -lt 2 ]
then
echo "$usage" 1>&2
exit 1
fi
#
# Isolate the keyletter argument.
#
keyletters="$1"
shift
#
# Make sure that "a", "b", or "i" was given a "position" argument.
#
case "$keyletters" in
*[abi]*)
if [ $# -lt 2 ]
then
echo $usage 1>&2
exit 1
fi
;;
esac
#
# Throw away leading "-" in keyletter argument.
#
case "$keyletters" in
-*)
keyletters=`expr "$keyletters" : "-\(.*\)"`
;;
esac
#
# See if the "s" keyletter was specified. If so, strip it out, and set
# "doranlib" so the archive will be ranlibbed afterwards.
#
case "$keyletters" in
*s*)
keyletters=`tr -d 's' <<EOF
$keyletters
EOF`
doranlib=true
;;
*)
doranlib=false
;;
esac
#
# Do the operation; if it fails, give up.
#
case "$keyletters" in
*[drqm]*)
doranlib=true
ar "$keyletters" "$@" || exit $?
;;
*)
ar "$keyletters" "$@" || exit $?
;;
esac
#
# If we are to "ranlib" the archive, do it.
#
if [ "$doranlib" = "true" ]
then
case "$keyletters" in
*[bai]*)
ranlib "$2" || exit $?
;;
*)
ranlib "$1" || exit $?
;;
esac
fi
exit 0

283
5bin/banner.c Normal file
View File

@@ -0,0 +1,283 @@
#ifndef lint
static char sccsid[] = "@(#)banner.c 1.1 92/07/30 SMI"; /* from S5R2 1.2 */
#endif
#include <stdio.h>
#define nchars 128 /*number of chars in char set*/
#define nlines 7 /*number of lines in a banner character*/
#define pposs 85 /*number of print positions on a line (must be multiple of 4)*/
/*followed by end of string character*/
#define pospch 8 /*number of char positions per banner char*/
#define chpln 10 /*number of banner characters per line*/
struct bann{
char alpha[nlines][pposs];
};
struct bann buffer, *bp = &buffer;
char ctbl[nchars][nlines] = {
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /*below 040*/
0,000,000,000,000,000,000, /* */
034,034,034,010,0,034,034, /*!*/
0167,0167,042,0,0,0,0, /*"*/
024,024,0177,024,0177,024,024, /*#*/
076,0111,0110,076,011,0111,076, /*$*/
0161,0122,0164,010,027,045,0107, /*%*/
030,044,030,070,0105,0102,071, /*&*/
034,034,010,020,0,0,0, /*'*/
014,020,040,040,040,020,014, /*(*/
030,4,2,2,2,4,030, /*)*/
0,042,024,0177,024,042,0, /***/
0,010,010,076,010,010,0, /*+*/
0,0,0,034,034,010,020, /*,*/
0,0,0,076,0,0,0, /*-*/
0,0,0,0,034,034,034, /*.*/
1,2,4,010,020,040,0100, /*/*/
034,042,0101,0101,0101,042,034, /*0*/
010,030,050,010,010,010,076, /*1*/
076,0101,1,076,0100,0100,0177, /*2*/
076,0101,1,076,1,0101,076, /*3*/
0100,0102,0102,0102,0177,2,2, /*4*/
0177,0100,0100,0176,1,0101,076, /*5*/
076,0101,0100,0176,0101,0101,076, /*6*/
0177,0102,04,010,020,020,020, /*7*/
076,0101,0101,076,0101,0101,076, /*8*/
076,0101,0101,077,1,0101,076, /*9*/
010,034,010,0,010,034,010, /*:*/
034,034,0,034,034,010,020, /*;*/
4,010,020,040,020,010,4, /*<*/
0,0,076,0,076,0,0, /*=*/
020,010,4,2,4,010,020, /*>*/
076,0101,1,016,010,0,010, /*?*/
076,0101,0135,0135,0136,0100,076, /*@*/
010,024,042,0101,0177,0101,0101, /*A*/
0176,0101,0101,0176,0101,0101,0176, /*B*/
076,0101,0100,0100,0100,0101,076, /*C*/
0176,0101,0101,0101,0101,0101,0176, /*D*/
0177,0100,0100,0174,0100,0100,0177, /*E*/
0177,0100,0100,0174,0100,0100,0100, /*F*/
076,0101,0100,0117,0101,0101,076, /*G*/
0101,0101,0101,0177,0101,0101,0101, /*H*/
034,010,010,010,010,010,034, /*I*/
1,1,1,1,0101,0101,076, /*J*/
0102,0104,0110,0160,0110,0104,0102, /*K*/
0100,0100,0100,0100,0100,0100,0177, /*L*/
0101,0143,0125,0111,0101,0101,0101, /*M*/
0101,0141,0121,0111,0105,0103,0101, /*N*/
0177,0101,0101,0101,0101,0101,0177, /*O*/
0176,0101,0101,0176,0100,0100,0100, /*P*/
076,0101,0101,0101,0105,0102,075, /*Q*/
0176,0101,0101,0176,0104,0102,0101, /*R*/
076,0101,0100,076,1,0101,076, /*S*/
0177,010,010,010,010,010,010, /*T*/
0101,0101,0101,0101,0101,0101,076, /*U*/
0101,0101,0101,0101,042,024,010, /*V*/
0101,0111,0111,0111,0111,0111,066, /*W*/
0101,042,024,010,024,042,0101, /*X*/
0101,042,024,010,010,010,010, /*Y*/
0177,2,4,010,020,040,0177, /*Z*/
076,040,040,040,040,040,076,/*[*/
0100,040,020,010,004,002,001, /*\*/
076,2,2,2,2,2,076, /*]*/
010,024,042,0,0,0,0, /*^*/
0,000,000,000,000,000,0177, /*_*/
034,034,010,04,0,0,0, /*`*/
0,014,022,041,077,041,041, /*A*/
0,076,041,076,041,041,076, /*B*/
0,036,041,040,040,041,036, /*C*/
0,076,041,041,041,041,076, /*D*/
0,077,040,076,040,040,077, /*E*/
0,077,040,076,040,040,040, /*F*/
0,036,041,040,047,041,036, /*G*/
0,041,041,077,041,041,041, /*H*/
0,004,004,004,004,004,004, /*I*/
0,001,001,001,001,041,036, /*J*/
0,041,042,074,044,042,041, /*K*/
0,040,040,040,040,040,077, /*L*/
0,041,063,055,041,041,041, /*M*/
0,041,061,051,045,043,041, /*N*/
0,036,041,041,041,041,036, /*O*/
0,076,041,041,076,040,040, /*P*/
0,036,041,041,045,042,035, /*Q*/
0,076,041,041,076,042,041, /*R*/
0,036,040,036,001,041,036, /*S*/
0,037,004,004,004,004,004, /*T*/
0,041,041,041,041,041,036, /*U*/
0,041,041,041,041,022,014, /*V*/
0,041,041,041,055,063,041, /*W*/
0,041,022,014,014,022,041, /*X*/
0,021,012,004,004,004,004, /*Y*/
0,077,002,004,010,020,077, /*Z*/
034,040,040,0140,040,040,034, /*{*/
010,010,010,0,010,010,010, /*|*/
034,2,2,3,2,2,034, /*}*/
060,0111,06,0,0,0,0, /*~*/
0,000,000,000,000,000,000 /*DEL*/
};
char blank = ' ';
char plot = '#';
int msk = 0100; /* ? */
main(argc,argp)
char **argp;int argc;
{
int i;
/*if invoked with no arguments, prints error comment;
if invoked with an argument, prints it in banner form.
*/
if(argc<2){
fprintf(stderr,"Usage: banner \"up to 10 char arg string\" . . .\n");
exit(1);
}
for(i = 1; i<argc ; ++i) {
banner(argp[i],bp);
banprt(bp);
printf("\n");
}
exit(0);
}
banner(s,bufp)
char *s;struct bann *bufp;
{
char c,*p,*q;
char convert();
struct bann *r;
p=s;
r=bufp;
banset(blank,bufp);
while((c= *s++)!=0 && (s-p)<=chpln){
if ((c & 0300)) { /* 8th bit is on */
c = convert (c);
}
q=ctbl[c];
banfil(q,r);
r = (struct bann *)((char *)r + pospch);
}
}
banfil(c,p)
char *c;
struct bann *p;
{
int i,j;
for(i=0;i<nlines;i++){
for(j=0;j<pospch;j++){
if(((c[i]<<j)&msk)!=0)p->alpha[i][j] = plot;
}
}
return(0);
}
banset(c,p)
char c;
struct bann *p;
{
int i,j;
for(i=0;i<nlines;i++)
for(j=0;j<pposs-1;j++)
p->alpha[i][j] = c;
}
banprt(ptr)
struct bann *ptr;
{
int i,j;
for(i=0;i<nlines;i++){
ptr->alpha[i][pposs-1]='\0';
for(j=pposs-2;j>=0;j--){
if(ptr->alpha[i][j]!=blank)break;
ptr->alpha[i][j]='\0';
}
printf("%s\n",ptr->alpha[i]);
}
}
char
convert (c)
unsigned char c;
{
if (c >= 0xc0 && c <= 0xc6)
return ('A');
if (c >= 0xc8 && c <= 0xcb)
return ('E');
if (c == 0xc7)
return ('C');
if (c >= 0xcc && c <= 0xcf)
return ('I');
if (c == 0xd0)
return ('D');
if (c == 0xd1)
return ('N');
if (c >= 0xd2 && c <= 0xd6)
return ('O');
if (c == 0xd7)
return ('X');
if (c == 0xd8)
return ('O');
if (c >= 0xd9 && c <= 0xdc)
return ('U');
if (c == 0xdd)
return ('Y');
if (c == 0xde)
return ('P');
if (c == 0xdf)
return ('B');
if (c >= 0xe0 && c <= 0xe6)
return ('a');
if (c == 0xe7)
return ('c');
if (c >= 0xe8 && c <= 0xeb)
return ('e');
if (c >= 0xec && c <= 0xef)
return ('i');
if (c == 0xf0)
return ('d');
if (c == 0xf1)
return ('n');
if (c >= 0xf2 && c <= 0xf6)
return ('o');
if (c >= 0xf9 && c <= 0xfc)
return ('u');
if (c == 0xfd)
return ('y');
if (c == 0xfe)
return ('p');
if (c == 0xff)
return ('y');
return (c & 0177);
}

450
5bin/cat.c Normal file
View File

@@ -0,0 +1,450 @@
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)cat.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.14 */
#endif
/*
** Concatenate files.
*/
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#define IDENTICAL(A,B) ((A).st_dev==(B).st_dev && (A).st_ino==(B).st_ino)
#define ISBLK(A) (((A).st_mode & S_IFMT) == S_IFBLK)
#define ISCHR(A) (((A).st_mode & S_IFMT) == S_IFCHR)
#define ISDIR(A) (((A).st_mode & S_IFMT) == S_IFDIR)
#define ISFIFO(A) (((A).st_mode & S_IFMT) == S_IFIFO)
#define ISREG(A) (((A).st_mode & S_IFMT) == S_IFREG)
int silent = 0; /* s flag */
int visi_mode = 0; /* v flag */
int visi_tab = 0; /* t flag */
int visi_newline = 0; /* e flag */
int ibsize;
int obsize;
main(argc, argv)
int argc;
char **argv;
{
register FILE *fi;
register char *filenm;
register int c;
extern int optind;
int errflg = 0;
int stdinflg = 0;
int status = 0;
struct stat source, target;
#ifdef STANDALONE
/*
* If the first argument is NULL,
* discard arguments until we find cat.
*/
if (argv[0][0] == '\0')
argc = getargv ("cat", &argv, 0);
#else
(void) setlocale(LC_ALL, "");
#endif
/*
* Process the options for cat.
*/
while( (c=getopt(argc,argv,"usvte")) != EOF ) {
switch(c) {
case 'u':
/*
* If not standalone, set stdout to
* completely unbuffered I/O when
* the 'u' option is used.
*/
#ifndef STANDALONE
setbuf(stdout, (char *)NULL);
#endif
continue;
case 's':
/*
* The 's' option requests silent mode
* where no messages are written.
*/
silent++;
continue;
case 'v':
/*
* The 'v' option requests that non-printing
* characters (with the exception of newlines,
* form-feeds, and tabs) be displayed visibly.
*
* Control characters are printed as "^x".
* DEL characters are printed as "^?".
* Non-printable and non-contrlol characters with the
* 8th bit set are printed as "M-x".
*/
visi_mode++;
continue;
case 't':
/*
* When in visi_mode, this option causes tabs
* to be displayed as "^I".
*/
visi_tab++;
continue;
case 'e':
/*
* When in visi_mode, this option causes newlines
* and form-feeds to be displayed as "$" at the end
* of the line prior to the newline.
*/
visi_newline++;
continue;
case '?':
errflg++;
break;
}
break;
}
if (errflg) {
if (!silent)
fprintf(stderr,"usage: cat -usvte [-|file] ...\n");
exit(2);
}
/*
* Stat stdout to be sure it is defined.
*/
if(fstat(fileno(stdout), &target) < 0) {
if(!silent) {
fprintf(stderr, "cat: cannot stat standard output: ");
perror("");
}
exit(2);
}
obsize = target.st_blksize;
/*
* If no arguments given, then use stdin for input.
*/
if (optind == argc) {
argc++;
stdinflg++;
}
/*
* Process each remaining argument,
* unless there is an error with stdout.
*/
for (argv = &argv[optind];
optind < argc && !ferror(stdout); optind++, argv++) {
filenm = *argv;
/*
* If the argument was '-' or there were no files
* specified, take the input from stdin.
*/
if (stdinflg || (filenm[0]=='-' && filenm[1]=='\0')) {
filenm = "standard input";
fi = stdin;
} else {
/*
* Attempt to open each specified file.
*/
if ((fi = fopen(filenm, "r")) == NULL) {
if (!silent) {
fprintf(stderr, "cat: cannot open %s: ",
filenm);
perror("");
}
status = 2;
continue;
}
}
/*
* Stat source to make sure it is defined.
*/
if(fstat(fileno(fi), &source) < 0) {
if(!silent) {
fprintf(stderr, "cat: cannot stat %s: ", filenm);
perror("");
}
status = 2;
continue;
}
/*
* If the source is not a character special file or a
* block special file, make sure it is not identical
* to the target.
*/
if (!ISCHR(target)
&& !ISBLK(target)
&& IDENTICAL(target, source)) {
if(!silent)
fprintf(stderr, "cat: input/output files '%s' identical\n",
stdinflg?"-": *argv);
if (fclose(fi) != 0 ) {
fprintf(stderr, "cat: close error: ");
perror("");
}
status = 2;
continue;
}
ibsize = source.st_blksize;
/*
* If in visible mode, use vcat; otherwise, use cat.
*/
if (visi_mode)
status = vcat(fi, filenm);
else
status = cat(fi, &source, filenm);
/*
* If the input is not stdin, flush stdout.
*/
if (fi!=stdin) {
fflush(stdout);
/*
* Attempt to close the source file.
*/
if (fclose(fi) != 0)
if (!silent) {
fprintf(stderr, "cat: close error: ");
perror("");
}
}
}
/*
* When all done, flush stdout to make sure data was written.
*/
fflush(stdout);
/*
* Display any error with stdout operations.
*/
if (ferror(stdout)) {
if (!silent) {
fprintf (stderr, "cat: output error: ");
perror("");
}
status = 2;
}
exit(status);
/* NOTREACHED */
}
#define MAXMAPSIZE (1024*1024) /* map at most 1MB */
int
cat(fi, statp, filenm)
FILE *fi;
register struct stat *statp;
char *filenm;
{
register int nitems;
register int nwritten;
register int offset;
register int fi_desc;
register int buffsize;
register char *bufferp;
int mapsize, munmapsize;
register off_t filesize;
register off_t mapoffset;
extern char *mmap();
extern char *malloc();
if (ISREG(*statp)) {
mapsize = MAXMAPSIZE;
if (statp->st_size < mapsize)
mapsize = statp->st_size;
munmapsize = mapsize;
/*
* Mmap time!
*/
bufferp = mmap((caddr_t)NULL, mapsize, PROT_READ, MAP_SHARED,
fileno(fi), (off_t)0);
if (bufferp == (caddr_t)-1)
mapsize = 0; /* I guess we can't mmap today */
} else
mapsize = 0; /* can't mmap non-regular files */
if (mapsize != 0) {
mapoffset = 0;
filesize = statp->st_size;
for (;;) {
if (write(fileno(stdout), bufferp, mapsize) < 0) {
if (!silent)
perror("cat: output error");
(void) munmap(bufferp, munmapsize);
return(2);
}
filesize -= mapsize;
if (filesize == 0)
break;
mapoffset += mapsize;
if (filesize < mapsize)
mapsize = filesize;
if (mmap(bufferp, mapsize, PROT_READ,
MAP_SHARED|MAP_FIXED, fileno(fi),
mapoffset) == (caddr_t)-1) {
if (!silent)
perror("cat: mmap error");
(void) munmap(bufferp, munmapsize);
return(1);
}
}
(void) munmap(bufferp, munmapsize);
} else {
if (obsize)
buffsize = obsize; /* common case, use output blksize */
else if (ibsize)
buffsize = ibsize;
else
buffsize = BUFSIZ;
if ((bufferp = malloc(buffsize)) == NULL) {
perror("cat: no memory");
return (1);
}
fi_desc = fileno(fi);
/*
* While not end of file, copy blocks to stdout.
*/
while ((nitems=read(fi_desc,bufferp,buffsize)) > 0) {
offset = 0;
/*
* Note that on some systems (V7), very large writes
* to a pipe return less than the requested size of
* the write. In this case, multiple writes are
* required.
*/
do {
nwritten = write(1,bufferp+offset,
(unsigned)nitems);
if (nwritten < 0) {
if (!silent) {
fprintf(stderr, "cat: output error: ");
perror("");
}
free(bufferp);
return(2);
}
offset += nwritten;
} while ((nitems -= nwritten) > 0);
}
free(bufferp);
if (nitems < 0) {
fprintf(stderr, "cat: input error on %s: ", filenm);
perror("");
}
}
return(0);
}
vcat(fi, filenm)
FILE *fi;
char *filenm;
{
register int c;
while ((c = getc(fi)) != EOF)
{
if ( (c == '\t') || (c == '\f') ) {
/*
* Display tab as "^I" and formfeed as ^L
* if visi_tab set
*/
if (! visi_tab)
putchar(c);
else {
putchar('^');
putchar(c^0100);
}
} else if ( c == '\n') {
/*
* Display newlines as "$<newline>"
* if visi_newline set
*/
if (visi_newline)
putchar('$');
putchar(c);
} else {
/*
* For non-printable and non-cntrl chars,
* use the "M-x" notation.
*/
if (c >= 0200 && !isprint(c) && !iscntrl(c)) {
putchar('M');
putchar('-');
c &= 0177;
}
if (isprint(c))
putchar(c);
else if (c < ' ')
printf("^%c", c+'@');
else if (c == 0177)
printf("^?");
else
putchar(c);
}
}
if (ferror(fi)) {
fprintf(stderr, "cat: input error on %s: ", filenm);
perror("");
}
return(0);
}

362
5bin/df.c Normal file
View File

@@ -0,0 +1,362 @@
#ifndef lint
static char sccsid[] = "@(#)df.c 1.1 92/07/30 SMI"; /* from UCB 4.18 84/02/02 */
#endif
/*
* df
*/
#include <sys/param.h>
#include <errno.h>
#include <ufs/fs.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <stdio.h>
#include <mntent.h>
void usage(), pheader();
char *mpath();
int tflag;
int aflag;
char *typestr;
union {
struct fs iu_fs;
char dummy[SBSIZE];
} sb;
#define sblock sb.iu_fs
/*
* This structure is used to build a list of mntent structures
* in reverse order from /etc/mtab.
*/
struct mntlist {
struct mntent *mntl_mnt;
struct mntlist *mntl_next;
};
struct mntlist *mkmntlist();
struct mntent *mntdup();
int
main(argc, argv)
int argc;
char **argv;
{
register struct mntent *mnt;
/*
* Skip over command name, if present.
*/
if (argc > 0) {
argv++;
argc--;
}
while (argc > 0 && (*argv)[0]=='-') {
switch ((*argv)[1]) {
case 't':
tflag++;
break;
default:
usage();
}
argc--, argv++;
}
sync();
if (argc <= 0) {
register FILE *mtabp;
if ((mtabp = setmntent(MOUNTED, "r")) == NULL) {
(void) fprintf(stderr, "df: ");
perror(MOUNTED);
exit(1);
}
pheader();
while ((mnt = getmntent(mtabp)) != NULL) {
if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0)
continue;
dfreemnt(mnt->mnt_dir, mnt);
}
(void) endmntent(mtabp);
} else {
int num = argc ;
int i ;
struct mntlist *mntl ;
pheader();
aflag++;
/*
* Reverse the list and start comparing.
*/
for (mntl = mkmntlist(); mntl != NULL && num ;
mntl = mntl->mntl_next) {
struct stat dirstat, filestat ;
mnt = mntl->mntl_mnt ;
if (stat(mnt->mnt_dir, &dirstat)<0) {
continue ;
}
for (i = 0; i < argc; i++) {
if (argv[i]==NULL) continue ;
if (stat(argv[i], &filestat) < 0) {
(void) fprintf(stderr, "df: ");
perror(argv[i]);
argv[i] = NULL ;
--num;
} else {
if ((filestat.st_mode & S_IFMT) == S_IFBLK ||
(filestat.st_mode & S_IFMT) == S_IFCHR) {
char *cp ;
cp = mpath(argv[i]);
if (*cp == '\0') {
dfreedev(argv[i]);
argv[i] = NULL ;
--num;
continue;
}
else {
if (stat(cp, &filestat) < 0) {
(void) fprintf(stderr, "df: ");
perror(argv[i]);
argv[i] = NULL ;
--num;
continue ;
}
}
}
if (strcmp(mnt->mnt_type, MNTTYPE_IGNORE) == 0 ||
strcmp(mnt->mnt_type, MNTTYPE_SWAP) == 0)
continue;
if ((filestat.st_dev == dirstat.st_dev)) {
dfreemnt(mnt->mnt_dir, mnt);
argv[i] = NULL ;
--num ;
}
}
}
}
if (num) {
for (i = 0; i < argc; i++)
if (argv[i]==NULL)
continue ;
else
(void) fprintf(stderr,
"Could not find mount point for %s\n", argv[i]) ;
}
}
exit(0);
/*NOTREACHED*/
}
void
pheader()
{
(void) printf("Filesystem bavail iavail");
if (tflag)
(void) printf(" btotal itotal");
(void) printf(" Mounted on\n");
}
/*
* Report on a block or character special device. Assumed not to be
* mounted. N.B. checks for a valid 4.2BSD superblock.
*/
dfreedev(file)
char *file;
{
long availblks, avail, free, used;
int fi;
fi = open(file, 0);
if (fi < 0) {
(void) fprintf(stderr, "df: ");
perror(file);
return;
}
if (bread(file, fi, SBLOCK, (char *)&sblock, SBSIZE) == 0) {
(void) close(fi);
return;
}
if (sblock.fs_magic != FS_MAGIC) {
(void) fprintf(stderr, "df: %s: not a UNIX filesystem\n",
file);
(void) close(fi);
return;
}
(void) printf("%-20.20s", file);
free = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
sblock.fs_cstotal.cs_nffree;
availblks = sblock.fs_dsize * (100 - sblock.fs_minfree) / 100;
used = sblock.fs_dsize - free;
avail = availblks > (sblock.fs_dsize - free) ? availblks - used : 0;
(void) printf("%8d%8ld", avail * sblock.fs_fsize / 512,
sblock.fs_cstotal.cs_nifree);
if (tflag) {
(void) printf("%8d%8ld", sblock.fs_dsize * sblock.fs_fsize / 512,
sblock.fs_ncg * sblock.fs_ipg);
}
(void) printf(" %s\n", mpath(file));
(void) close(fi);
}
dfreemnt(file, mnt)
char *file;
struct mntent *mnt;
{
struct statfs fs;
if (statfs(file, &fs) < 0) {
(void) fprintf(stderr, "df: ");
perror(file);
return;
}
if (!aflag && fs.f_blocks == 0) {
return;
}
if (strlen(mnt->mnt_fsname) > 20) {
(void) printf("%s\n", mnt->mnt_fsname);
(void) printf(" ");
} else {
(void) printf("%-20.20s", mnt->mnt_fsname);
}
(void) printf("%8d%8ld", fs.f_bavail* fs.f_bsize / 512, fs.f_ffree);
if (tflag) {
(void) printf("%8d%8ld", fs.f_blocks * fs.f_bsize / 512,
fs.f_files);
}
(void) printf(" %s\n", mnt->mnt_dir);
}
/*
* Given a name like /dev/rrp0h, returns the mounted path, like /usr.
*/
char *
mpath(file)
char *file;
{
FILE *mntp;
register struct mntent *mnt;
if ((mntp = setmntent(MOUNTED, "r")) == 0) {
(void) fprintf(stderr, "df: ");
perror(MOUNTED);
exit(1);
}
while ((mnt = getmntent(mntp)) != 0) {
if (strcmp(file, mnt->mnt_fsname) == 0) {
(void) endmntent(mntp);
return (mnt->mnt_dir);
}
}
(void) endmntent(mntp);
return "";
}
long lseek();
int
bread(file, fi, bno, buf, cnt)
char *file;
int fi;
daddr_t bno;
char *buf;
int cnt;
{
register int n;
extern int errno;
(void) lseek(fi, (long)(bno * DEV_BSIZE), 0);
if ((n = read(fi, buf, (unsigned) cnt)) < 0) {
/* probably a dismounted disk if errno == EIO */
if (errno != EIO) {
(void) fprintf(stderr, "df: read error on ");
perror(file);
(void) fprintf(stderr, "bno = %ld\n", bno);
} else {
(void) fprintf(stderr, "df: premature EOF on %s\n",
file);
(void) fprintf(stderr,
"bno = %ld expected = %d count = %d\n", bno, cnt, n);
}
return (0);
}
return (1);
}
char *
xmalloc(size)
unsigned int size;
{
register char *ret;
char *malloc();
if ((ret = (char *)malloc(size)) == NULL) {
(void) fprintf(stderr, "umount: ran out of memory!\n");
exit(1);
}
return (ret);
}
struct mntent *
mntdup(mnt)
register struct mntent *mnt;
{
register struct mntent *new;
new = (struct mntent *)xmalloc(sizeof(*new));
new->mnt_fsname = (char *)xmalloc(strlen(mnt->mnt_fsname) + 1);
(void) strcpy(new->mnt_fsname, mnt->mnt_fsname);
new->mnt_dir = (char *)xmalloc(strlen(mnt->mnt_dir) + 1);
(void) strcpy(new->mnt_dir, mnt->mnt_dir);
new->mnt_type = (char *)xmalloc(strlen(mnt->mnt_type) + 1);
(void) strcpy(new->mnt_type, mnt->mnt_type);
new->mnt_opts = (char *)xmalloc(strlen(mnt->mnt_opts) + 1);
(void) strcpy(new->mnt_opts, mnt->mnt_opts);
new->mnt_freq = mnt->mnt_freq;
new->mnt_passno = mnt->mnt_passno;
return (new);
}
void
usage()
{
(void) fprintf(stderr, "usage: df [ -t ] [ file... ]\n");
exit(0);
}
struct mntlist *
mkmntlist()
{
FILE *mounted;
struct mntlist *mntl;
struct mntlist *mntst = NULL;
struct mntent *mnt;
if ((mounted = setmntent(MOUNTED, "r"))== NULL) {
(void) fprintf(stderr, "df : ") ;
perror(MOUNTED);
exit(1);
}
while ((mnt = getmntent(mounted)) != NULL) {
mntl = (struct mntlist *)xmalloc(sizeof(*mntl));
mntl->mntl_mnt = mntdup(mnt);
mntl->mntl_next = mntst;
mntst = mntl;
}
(void) endmntent(mounted);
return(mntst);
}

23
5bin/diff3/Makefile Normal file
View File

@@ -0,0 +1,23 @@
#
# @(#)Makefile 1.1 92/07/30 SMI; from S5R2 1.5
#
# diff3 make file
IFLAG =
CFLAGS = -O
LDFLAGS = $(IFLAG)
CC = /usr/5bin/cc
MAKE = make
.DEFAULT:
sccs get $@
diff3prog: diff3prog.c
$(CC) $(CFLAGS) $(LDFLAGS) -o diff3prog diff3prog.c
install: diff3prog diff3.sh
install -c diff3.sh $(DESTDIR)/usr/5bin/diff3
install -s diff3prog $(DESTDIR)/usr/5lib
clean:
rm -f diff3prog

23
5bin/diff3/diff3.sh Normal file
View File

@@ -0,0 +1,23 @@
#! /bin/sh
#
# %Z%%M% %I% %E% SMI; from S5R2 1.2
#
PATH=/usr/5bin:/bin:/usr/bin
e=
case $1 in
-*)
e=$1
shift;;
esac
if test $# = 3 -a -f $1 -a -f $2 -a -f $3
then
:
else
echo usage: diff3 file1 file2 file3 1>&2
exit
fi
trap "rm -f /tmp/d3[ab]$$" 0 1 2 13 15
diff $1 $3 >/tmp/d3a$$
diff $2 $3 >/tmp/d3b$$
/usr/5lib/diff3prog $e /tmp/d3[ab]$$ $1 $2 $3

431
5bin/diff3/diff3prog.c Normal file
View File

@@ -0,0 +1,431 @@
#ifndef lint
static char sccsid[] = "@(#)diff3prog.c 1.1 92/07/30 SMI"; /* from S5R2 1.3 */
#endif
#include <stdio.h>
#
/* diff3 - 3-way differential file comparison*/
/* diff3 [-e] d13 d23 f1 f2 f3
*
* d13 = diff report on f1 vs f3
* d23 = diff report on f2 vs f3
* f1, f2, f3 the 3 files
*/
struct range {int from,to; };
/* from is first in range of changed lines
* to is last+1
* from=to=line after point of insertion
* for added lines
*/
struct diff {struct range old, new;};
#define NC 200
/* de is used to gather editing scripts,
* that are later spewed out in reverse order.
* its first element must be all zero
* the "new" component of de contains line positions
* or byte positions depending on when you look(!?)
*/
struct diff d13[NC];
struct diff d23[NC];
struct diff de[NC];
char line[256];
FILE *fp[3];
int linct[3] = {0,0,0};
/* the number of the last-read line in each file
* is kept in cline[0-2]
*/
int cline[3];
/* the latest known correspondence between line
* numbers of the 3 files is stored in last[1-3]
*/
int last[4];
int eflag;
int debug = 0;
main(argc,argv)
char **argv;
{
register i,m,n;
if(*argv[1]=='-') {
switch(argv[1][1]) {
default:
eflag = 3;
break;
case '3':
eflag = 2;
break;
case 'x':
eflag = 1;
}
argv++;
argc--;
}
if(argc<6) {
fprintf(stderr,"diff3: arg count\n");
exit(1);
}
m = readin(argv[1],d13);
n = readin(argv[2],d23);
for(i=0;i<=2;i++)
if((fp[i] = fopen(argv[i+3],"r")) == NULL) {
printf("diff3: can't open %s\n",argv[i+3]);
exit(1);
}
merge(m,n);
exit(0);
/* NOTREACHED */
}
/*pick up the line numbers of allcahnges from
* one change file
* (this puts the numbers in a vector, which is not
* strictly necessary, since the vector is processed
* in one sequential pass. The vector could be optimized
* out of existence)
*/
readin(name,dd)
char *name;
struct diff *dd;
{
register i;
int a,b,c,d;
char kind;
char *p;
fp[0] = fopen(name,"r");
for(i=0;getchange(fp[0]);i++) {
if(i>=NC) {
fprintf(stderr,"diff3: too many changes\n");
exit(0);
}
p = line;
a = b = number(&p);
if(*p==',') {
p++;
b = number(&p);
}
kind = *p++;
c = d = number(&p);
if(*p==',') {
p++;
d = number(&p);
}
if(kind=='a')
a++;
if(kind=='d')
c++;
b++;
d++;
dd[i].old.from = a;
dd[i].old.to = b;
dd[i].new.from = c;
dd[i].new.to = d;
}
dd[i].old.from = dd[i-1].old.to;
dd[i].new.from = dd[i-1].new.to;
fclose(fp[0]);
return(i);
}
number(lc)
char **lc;
{
register nn;
nn = 0;
while(digit(**lc))
nn = nn*10 + *(*lc)++ - '0';
return(nn);
}
digit(c)
{
return(c>='0'&&c<='9');
}
getchange(b)
FILE *b;
{
while(getline(b))
if(digit(line[0]))
return(1);
return(0);
}
getline(b)
FILE *b;
{
register i, c;
for(i=0;i<sizeof(line)-1;i++) {
c = getc(b);
if(c==EOF)
break;
line[i] = c;
if(c=='\n') {
line[++i] = 0;
return(i);
}
}
return(0);
}
merge(m1,m2)
{
register struct diff *d1, *d2, *d3;
int dup;
int j;
int t1,t2;
d1 = d13;
d2 = d23;
j = 0;
for(;(t1 = d1<d13+m1) | (t2 = d2<d23+m2);) {
if(debug) {
printf("%d,%d=%d,%d %d,%d=%d,%d\n",
d1->old.from,d1->old.to,
d1->new.from,d1->new.to,
d2->old.from,d2->old.to,
d2->new.from,d2->new.to);
}
/* first file is different from others*/
if(!t2||t1&&d1->new.to < d2->new.from) {
/* stuff peculiar to 1st file */
if(eflag==0) {
separate("1");
change(1,&d1->old,0);
keep(2,&d1->old,&d1->new);
change(3,&d1->new,0);
}
d1++;
continue;
}
/* second file is different from others*/
if(!t1||t2&&d2->new.to < d1->new.from) {
if(eflag==0) {
separate("2");
keep(1,&d2->old,&d2->new);
change(2,&d2->old,0);
change(3,&d2->new,0);
}
d2++;
continue;
}
/* merge overlapping changes in first file
* this happens after extension see below*/
if(d1+1<d13+m1 &&
d1->new.to>=d1[1].new.from) {
d1[1].old.from = d1->old.from;
d1[1].new.from = d1->new.from;
d1++;
continue;
}
/* merge overlapping changes in second*/
if(d2+1<d23+m2 &&
d2->new.to>=d2[1].new.from) {
d2[1].old.from = d2->old.from;
d2[1].new.from = d2->new.from;
d2++;
continue;
}
/* stuff peculiar to third file or different in all*/
if(d1->new.from==d2->new.from&&
d1->new.to==d2->new.to) {
dup = duplicate(&d1->old,&d2->old);
/* dup=0 means all files differ
* dup =1 meands files 1&2 identical*/
if(eflag==0) {
separate(dup?"3":"");
change(1,&d1->old,dup);
change(2,&d2->old,0);
d3 = d1->old.to>d1->old.from?d1:d2;
change(3,&d3->new,0);
} else
j = edit(d1,dup,j);
d1++;
d2++;
continue;
}
/* overlapping changes from file1 & 2
* extend changes appropriately to
* make them coincide*/
if(d1->new.from<d2->new.from) {
d2->old.from -= d2->new.from-d1->new.from;
d2->new.from = d1->new.from;
}
else if(d2->new.from<d1->new.from) {
d1->old.from -= d1->new.from-d2->new.from;
d1->new.from = d2->new.from;
}
if(d1->new.to >d2->new.to) {
d2->old.to += d1->new.to - d2->new.to;
d2->new.to = d1->new.to;
}
else if(d2->new.to >d1->new.to) {
d1->old.to += d2->new.to - d1->new.to;
d1->new.to = d2->new.to;
}
}
if(eflag) {
edscript(j);
if(j)
printf("w\nq\n");
}
}
separate(s)
char *s;
{
printf("====%s\n",s);
}
/* the range of ines rold.from thru rold.to in file i
* is to be changed. it is to be printed only if
* it does not duplicate something to be printed later
*/
change(i,rold,dup)
struct range *rold;
{
printf("%d:",i);
last[i] = rold->to;
prange(rold);
if(dup)
return;
if(debug)
return;
i--;
skip(i,rold->from,(char *)0);
skip(i,rold->to," ");
}
/* print the range of line numbers, rold.from thru rold.to
* as n1,n2 or n1
*/
prange(rold)
struct range *rold;
{
if(rold->to<=rold->from)
printf("%da\n",rold->from-1);
else {
printf("%d",rold->from);
if(rold->to > rold->from+1)
printf(",%d",rold->to-1);
printf("c\n");
}
}
/* no difference was reported by diff between file 1(or 2)
* and file 3, and an artificial dummy difference (trange)
* must be ginned up to correspond to the change reported
* in the other file
*/
keep(i,rold,rnew)
struct range *rold, *rnew;
{
register delta;
struct range trange;
delta = last[3] - last[i];
trange.from = rnew->from - delta;
trange.to = rnew->to - delta;
change(i,&trange,1);
}
/* skip to just befor line number from in file i
* if "pr" is nonzero, print all skipped stuff
* w with string pr as a prefix
*/
skip(i,from,pr)
char *pr;
{
register j,n;
for(n=0;cline[i]<from-1;n+=j) {
if((j=getline(fp[i]))==0)
trouble();
if(pr)
printf("%s%s",pr,line);
cline[i]++;
}
return(n);
}
/* return 1 or 0 according as the old range
* (in file 1) contains exactly the same data
* as the new range (in file 2)
*/
duplicate(r1,r2)
struct range *r1, *r2;
{
register c,d;
register nchar;
int nline;
if(r1->to-r1->from != r2->to-r2->from)
return(0);
skip(0,r1->from,(char *)0);
skip(1,r2->from,(char *)0);
nchar = 0;
for(nline=0;nline<r1->to-r1->from;nline++) {
do {
c = getc(fp[0]);
d = getc(fp[1]);
if(c== -1||d== -1)
trouble();
nchar++;
if(c!=d) {
repos(nchar);
return(0);
}
} while(c!= '\n');
}
repos(nchar);
return(1);
}
repos(nchar)
{
register i;
for(i=0;i<2;i++)
fseek(fp[i], (long)-nchar, 1);
}
trouble()
{
fprintf(stderr,"diff3: logic error\n");
abort();
}
/* collect an editing script for later regurgitation
*/
edit(diff,dup,j)
struct diff *diff;
{
if(((dup+1)&eflag)==0)
return(j);
j++;
de[j].old.from = diff->old.from;
de[j].old.to = diff->old.to;
de[j].new.from = de[j-1].new.to
+skip(2,diff->new.from,(char *)0);
de[j].new.to = de[j].new.from
+skip(2,diff->new.to,(char *)0);
return(j);
}
/* regurgitate */
edscript(n)
{
register j,k;
char block[BUFSIZ];
for(n=n; n>0; n--) {
prange(&de[n].old);
fseek(fp[2], (long)de[n].new.from, 0);
for(k=de[n].new.to-de[n].new.from;k>0;k-= j) {
j = k>BUFSIZ?BUFSIZ:k;
if(fread(block,1,j,fp[2])!=j)
trouble();
fwrite(block, 1, j, stdout);
}
printf(".\n");
}
}

83
5bin/dircmp.sh Normal file
View File

@@ -0,0 +1,83 @@
#! /bin/sh
#
# %Z%%M% %I% %E% SMI; from S5R2 1.3
#
PATH=/usr/5bin:/bin:/usr/bin
USAGE="dircmp: usage: dircmp -s -d -wn directory directory"
trap "rm -f /usr/tmp/dc$$*;exit" 1 2 3 15
width=72
set -- `getopt dsw: $*`
if [ $? != 0 ]
then
echo $USAGE
exit 2
fi
for i in $*
do
case $i in
-d) Dflag="yes"; shift;;
-s) Sflag="yes"; shift;;
-w) width=`expr $2 + 0 2>/dev/null`
if [ $? = 2 ]
then echo "dircmp: numeric argument required"
exit 2
fi
shift 2
;;
--) shift; break;;
esac
done
D0=`pwd`
D1=$1
D2=$2
if [ $# -lt 2 ]
then echo $USAGE
exit 1
elif [ ! -d "$D1" ]
then echo $D1 not a directory !
exit 2
elif [ ! -d "$D2" ]
then echo $D2 not a directory !
exit 2
fi
cd $D1
find . -print | sort > /usr/tmp/dc$$a
cd $D0
cd $D2
find . -print | sort > /usr/tmp/dc$$b
comm /usr/tmp/dc$$a /usr/tmp/dc$$b | sed -n \
-e "/^ /w /usr/tmp/dc$$c" \
-e "/^ [^ ]/w /usr/tmp/dc$$d" \
-e "/^[^ ]/w /usr/tmp/dc$$e"
rm -f /usr/tmp/dc$$a /usr/tmp/dc$$b
pr -w${width} -h "$D1 only and $D2 only" -m /usr/tmp/dc$$e /usr/tmp/dc$$d
rm -f /usr/tmp/dc$$e /usr/tmp/dc$$d
sed -e s/..// < /usr/tmp/dc$$c > /usr/tmp/dc$$f
rm -f /usr/tmp/dc$$c
cd $D0
> /usr/tmp/dc$$g
while read a
do
if [ -d $D1/"$a" ]
then if [ "$Sflag" != "yes" ]
then echo "directory $a"
fi
elif [ -f $D1/"$a" ]
then cmp -s $D1/"$a" $D2/"$a"
if [ $? = 0 ]
then if [ "$Sflag" != "yes" ]
then echo "same $a"
fi
else echo "different $a"
if [ "$Dflag" = "yes" ]
then diff $D1/"$a" $D2/"$a" | pr -h "diff of $a in $D1 and $D2" >> /usr/tmp/dc$$g
fi
fi
elif [ "$Sflag" != "yes" ]
then echo "special $a"
fi
done < /usr/tmp/dc$$f | pr -r -h "Comparison of $D1 $D2"
if [ "$Dflag" = "yes" ]
then cat /usr/tmp/dc$$g
fi
rm -f /usr/tmp/dc$$*

206
5bin/du.c Normal file
View File

@@ -0,0 +1,206 @@
#ifndef lint
static char sccsid[] = "@(#)du.c 1.1 92/07/30 SMI"; /* from UCB 4.11 83/07/01 */
#endif
/*
** du -- summarize disk usage
** du [-ars] [name ...]
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dir.h>
char path[MAXPATHLEN+1], name[MAXPATHLEN+1];
int aflg;
int rflg;
int sflg;
char *dot = ".";
#define ML 1000
struct {
int dev;
ino_t ino;
} ml[ML];
int mlx;
long descend();
extern char *strchr(), *strrchr(), *strcpy();
#define nlb(n) (howmany(dbtob(n), 512))
main(argc, argv)
int argc;
char **argv;
{
long blocks = 0;
register c;
extern char *optarg;
extern int optind;
register char *np;
register int pid, wpid;
int status, retcode = 0;
while ((c = getopt(argc, argv, "ars")) != EOF)
switch(c) {
case 'a':
aflg++;
continue;
case 'r':
rflg++;
continue;
case 's':
sflg++;
continue;
default:
fprintf(stderr, "usage: du [-ars] [name ...]\n");
exit(2);
}
if (optind == argc) {
argv = &dot;
argc = 1;
optind = 0;
}
do {
if (optind < argc - 1) {
pid = fork();
if (pid == -1) {
perror("du: No more processes");
exit(1);
}
if (pid != 0) {
while ((wpid = wait(&status)) != pid
&& wpid != -1)
;
if (pid != -1) {
if (status != 0)
retcode = 1;
}
}
}
if (optind == argc - 1 || pid == 0) {
(void) strcpy(path, argv[optind]);
(void) strcpy(name, argv[optind]);
if (np = strrchr(name, '/')) {
*np++ = '\0';
if (chdir(*name ? name : "/") < 0) {
if (rflg) {
fprintf(stderr,
"du: ");
perror(*name ? name : "/");
}
exit(1);
}
} else
np = path;
blocks = descend(path, *np ? np : ".");
if (sflg)
printf("%ld\t%s\n", nlb(blocks), path);
if (optind < argc - 1)
exit(0);
}
optind++;
} while (optind < argc);
exit(retcode);
/* NOTREACHED */
}
DIR *dirp = NULL;
long
descend(base, name)
char *base, *name;
{
char *ebase0, *ebase;
struct stat stb;
int i;
long blocks = 0;
long curoff = 0;
register struct direct *dp;
ebase0 = ebase = strchr(base, 0);
if (ebase > base && ebase[-1] == '/')
ebase--;
if (lstat(name, &stb) < 0) {
if (rflg) {
fprintf(stderr, "du: ");
perror(base);
}
*ebase0 = 0;
return (0);
}
if (stb.st_nlink > 1 && (stb.st_mode&S_IFMT) != S_IFDIR) {
for (i = 0; i <= mlx; i++)
if (ml[i].ino == stb.st_ino && ml[i].dev == stb.st_dev)
return (0);
if (mlx < ML) {
ml[mlx].dev = stb.st_dev;
ml[mlx].ino = stb.st_ino;
mlx++;
}
}
blocks = stb.st_blocks;
if ((stb.st_mode&S_IFMT) != S_IFDIR) {
if (aflg)
printf("%ld\t%s\n", nlb(blocks), base);
return (blocks);
}
if (dirp != NULL)
closedir(dirp);
dirp = opendir(name);
if (dirp == NULL) {
if (rflg) {
fprintf(stderr, "du: ");
perror(base);
}
*ebase0 = 0;
return (0);
}
if (chdir(name) < 0) {
if (rflg) {
fprintf(stderr, "du: ");
perror(base);
}
*ebase0 = 0;
closedir(dirp);
dirp = NULL;
return (0);
}
while (dp = readdir(dirp)) {
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;
(void) sprintf(ebase, "/%s", dp->d_name);
curoff = telldir(dirp);
blocks += descend(base, ebase+1);
*ebase = 0;
if (dirp == NULL) {
dirp = opendir(".");
if (dirp == NULL) {
if (rflg) {
fprintf(stderr, "du: Can't reopen '.' in ");
perror(base);
}
return (0);
}
seekdir(dirp, curoff);
}
}
closedir(dirp);
dirp = NULL;
if (sflg == 0)
printf("%ld\t%s\n", nlb(blocks), base);
if (chdir("..") < 0) {
if (rflg) {
(void) sprintf(strchr(base, '\0'), "/..");
fprintf("du: Can't change directories to '..' in ");
perror(base);
}
exit(1);
}
*ebase0 = 0;
return (blocks);
}

69
5bin/echo.c Normal file
View File

@@ -0,0 +1,69 @@
#ifndef lint
static char sccsid[] = "@(#)echo.c 1.1 92/07/30 SMI"; /* from S5R2 1.2 */
#endif
main(argc, argv)
char **argv;
{
register char *cp;
register int i, wd;
int j;
if(--argc == 0) {
putchar('\n');
exit(0);
}
for(i = 1; i <= argc; i++) {
for(cp = argv[i]; *cp; cp++) {
if(*cp == '\\')
switch(*++cp) {
case 'b':
putchar('\b');
continue;
case 'c':
exit(0);
case 'f':
putchar('\f');
continue;
case 'n':
putchar('\n');
continue;
case 'r':
putchar('\r');
continue;
case 't':
putchar('\t');
continue;
case 'v':
putchar('\v');
continue;
case '\\':
putchar('\\');
continue;
case '0':
j = wd = 0;
while ((*++cp >= '0' && *cp <= '7') && j++ < 3) {
wd <<= 3;
wd |= (*cp - '0');
}
putchar(wd);
--cp;
continue;
default:
cp--;
}
putchar(*cp);
}
putchar(i == argc? '\n': ' ');
}
exit(0);
/* NOTREACHED */
}

413
5bin/expr.c Normal file
View File

@@ -0,0 +1,413 @@
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)expr.c 1.1 92/07/30 SMI"; /* from S5R3 1.13 */
#endif
# define A_STRING 258
# define NOARG 259
# define OR 260
# define AND 261
# define EQ 262
# define LT 263
# define GT 264
# define GEQ 265
# define LEQ 266
# define NEQ 267
# define ADD 268
# define SUBT 269
# define MULT 270
# define DIV 271
# define REM 272
# define MCH 273
# define MATCH 274
#define ESIZE 256
#define EQL(x,y) !strcmp(x,y)
#define INIT register char *sp = instring;
#define GETC() (*sp++)
#define PEEKC() (*sp)
#define UNGETC(c) (--sp)
#define RETURN(c) return
#define ERROR(c) errxx(c)
#include <regexp.h>
long atol();
char *ltoa(), *strcpy(), *strncpy();
void exit();
char **Av;
char *buf;
int Ac;
int Argi;
int noarg;
int paren;
char Mstring[1][128];
char *malloc();
char *operator[] = {
"|", "&", "+", "-", "*", "/", "%", ":",
"=", "==", "<", "<=", ">", ">=", "!=",
"match", "\0" };
int op[] = {
OR, AND, ADD, SUBT, MULT, DIV, REM, MCH,
EQ, EQ, LT, LEQ, GT, GEQ, NEQ,
MATCH };
int pri[] = {
1,2,3,3,3,3,3,3,4,4,5,5,5,6,7};
yylex() {
register char *p;
register i;
if(Argi >= Ac) return NOARG;
p = Av[Argi];
if((*p == '(' || *p == ')') && p[1] == '\0' )
return (int)*p;
for(i = 0; *operator[i]; ++i)
if(EQL(operator[i], p))
return op[i];
return A_STRING;
}
char *rel(oper, r1, r2) register char *r1, *r2;
{
register long i;
if(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$"))
i = atol(r1) - atol(r2);
else
i = strcmp(r1, r2);
switch(oper) {
case EQ:
i = i==0;
break;
case GT:
i = i>0;
break;
case GEQ:
i = i>=0;
break;
case LT:
i = i<0;
break;
case LEQ:
i = i<=0;
break;
case NEQ:
i = i!=0;
break;
}
return i? "1": "0";
}
char *arith(oper, r1, r2) char *r1, *r2;
{
long i1, i2;
register char *rv;
if(!(ematch(r1, "-\\{0,1\\}[0-9]*$") && ematch(r2, "-\\{0,1\\}[0-9]*$")))
yyerror("non-numeric argument");
i1 = atol(r1);
i2 = atol(r2);
switch(oper) {
case ADD:
i1 = i1 + i2;
break;
case SUBT:
i1 = i1 - i2;
break;
case MULT:
i1 = i1 * i2;
break;
case DIV:
if (i2 == 0)
yyerror("division by zero");
i1 = i1 / i2;
break;
case REM:
if (i2 == 0)
yyerror("division by zero");
i1 = i1 % i2;
break;
}
rv = malloc(16);
(void) strcpy(rv, ltoa(i1));
return rv;
}
char *conj(oper, r1, r2) char *r1, *r2;
{
register char *rv;
switch(oper) {
case OR:
if(EQL(r1, "0")
|| EQL(r1, ""))
if(EQL(r2, "0")
|| EQL(r2, ""))
rv = "0";
else
rv = r2;
else
rv = r1;
break;
case AND:
if(EQL(r1, "0")
|| EQL(r1, ""))
rv = "0";
else if(EQL(r2, "0")
|| EQL(r2, ""))
rv = "0";
else
rv = r1;
break;
}
return rv;
}
char *match(s, p)
char *s, *p;
{
register char *rv;
(void) strcpy(rv=malloc(8), ltoa((long)ematch(s, p)));
if(nbra) {
rv = malloc((unsigned) strlen(Mstring[0]) + 1);
(void) strcpy(rv, Mstring[0]);
}
return rv;
}
ematch(s, p)
char *s;
register char *p;
{
static char expbuf[ESIZE];
char *compile();
register num;
extern char *braslist[], *braelist[], *loc2;
compile(p, expbuf, &expbuf[ESIZE], 0);
if(nbra > 1)
yyerror("Too many '\\('s");
if(advance(s, expbuf)) {
if(nbra == 1) {
p = braslist[0];
num = braelist[0] - p;
if ((num > 127) || (num < 0)) yyerror("Paren problem");
(void) strncpy(Mstring[0], p, num);
Mstring[0][num] = '\0';
}
return(loc2-s);
}
return(0);
}
errxx(err)
register err;
{
register char *message;
switch(err) {
case 11:
message = "Range endpoint too large";
break;
case 16:
message = "Bad number";
break;
case 25:
message = "``\\digit'' out of range";
break;
case 36:
message = "Illegal or missing delimiter";
break;
case 41:
message = "No remembered search string";
break;
case 42:
message = "\\( \\) imbalance";
break;
case 43:
message = "Too many \\(";
break;
case 44:
message = "More than 2 numbers given in \\{ \\}";
break;
case 45:
message = "} expected after \\";
break;
case 46:
message = "First number exceeds second in \\{ \\}";
break;
case 49:
message = "[ ] imbalance";
break;
case 50:
message = "Regular expression too long";
break;
default:
message = "Unknown regexp error code!!";
break;
}
yyerror(message);
}
yyerror(s)
char *s;
{
(void) write(2, "expr: ", 6);
(void) write(2, s, (unsigned) strlen(s));
(void) write(2, "\n", 1);
exit(2);
}
char *ltoa(l)
long l;
{
static char str[20];
register char *sp;
register i;
register neg;
if(l == 0x80000000L)
return "-2147483648";
neg = 0;
if(l < 0)
++neg, l = -l;
sp = &str[20];
*--sp = '\0';
do {
i = l % 10;
*--sp = '0' + i;
l /= 10;
}
while(l);
if(neg)
*--sp = '-';
return sp;
}
char *expres(prior,par) int prior, par;
{
int ylex, temp, op1;
char *r1, *ra, *rb;
ylex = yylex();
if (ylex == ')' || (ylex >= NOARG && ylex < MATCH)) {
yyerror("syntax error");
}
if (ylex == A_STRING) {
r1 = Av[Argi++];
temp = Argi;
}
else {
if (ylex == '(') {
paren++;
Argi++;
r1 = expres(0,Argi);
Argi--;
}
temp = -1;
}
lop:
ylex = yylex();
if (ylex > NOARG && ylex < MATCH) {
op1 = ylex;
Argi++;
if (pri[op1-OR] <= prior )
return r1;
else {
switch(op1) {
case OR:
case AND:
r1 = conj(op1,r1,expres(pri[op1-OR],0));
break;
case EQ:
case LT:
case GT:
case LEQ:
case GEQ:
case NEQ:
r1=rel(op1,r1,expres(pri[op1-OR],0));
break;
case ADD:
case SUBT:
case MULT:
case DIV:
case REM:
r1=arith(op1,r1,expres(pri[op1-OR],0));
break;
case MCH:
r1=match(r1,expres(pri[op1-OR],0));
break;
}
if(noarg == 1) {
return r1;
}
Argi--;
goto lop;
}
}
ylex = yylex();
if(ylex == ')') {
if(par == Argi) {
yyerror("syntax error");
}
if(par != 0) {
paren--;
Argi++;
}
Argi++;
return r1;
}
ylex = yylex();
if(ylex > MCH && ylex <= MATCH) {
if (Argi == temp) {
return r1;
}
op1 = ylex;
Argi++;
switch(op1) {
case MATCH:
rb = expres(pri[op1-OR],0);
ra = expres(pri[op1-OR],0);
r1 = match(rb,ra);
break;
}
if(noarg == 1) {
return r1;
}
Argi--;
goto lop;
}
ylex = yylex();
if (ylex == NOARG) {
noarg = 1;
}
return r1;
}
main(argc, argv) char **argv;
{
Ac = argc;
Argi = 1;
noarg = 0;
paren = 0;
Av = argv;
buf = expres(0,1);
if(Ac != Argi || paren != 0) {
yyerror("syntax error");
}
(void) write(1, buf, (unsigned) strlen(buf));
(void) write(1, "\n", 1);
exit((!strcmp(buf, "0") || !buf[0])? 1: 0);
}

417
5bin/lint/sparc/Makefile Normal file
View File

@@ -0,0 +1,417 @@
#
# @(#)Makefile 1.1 92/07/30 SMI
# Makefile for "lint" and standard "lint" libraries
#
TARGET= SPARC
PCC = ../../../lang/pcc/sparc
include ../src/Makefile.common
# DO NOT DELETE THIS LINE -- make depend uses it
xdefs.o: $(MIP)/xdefs.c
xdefs.o: $(MIP)/cpass1.h
xdefs.o: ../src/machdep.h
xdefs.o: ./align.h
xdefs.o: $(MIP)/mip.h
xdefs.o: /usr/include/stdio.h
xdefs.o: ./ops.h
xdefs.o: $(PCCMIP)/pcc_ops.h
xdefs.o: ./types.h
xdefs.o: $(PCCMIP)/pcc_types.h
xdefs.o: ./node.h
xdefs.o: $(PCCMIP)/pcc_node.h
xdefs.o: ../src/machdep.h
xdefs.o: $(PCCMIP)/pcc_types.h
xdefs.o: ./symtab.h
xdefs.o: $(PCCMIP)/pcc_symtab.h
xdefs.ln: $(MIP)/xdefs.c
xdefs.ln: $(MIP)/cpass1.h
xdefs.ln: ../src/machdep.h
xdefs.ln: ./align.h
xdefs.ln: $(MIP)/mip.h
xdefs.ln: /usr/include/stdio.h
xdefs.ln: ./ops.h
xdefs.ln: $(PCCMIP)/pcc_ops.h
xdefs.ln: ./types.h
xdefs.ln: $(PCCMIP)/pcc_types.h
xdefs.ln: ./node.h
xdefs.ln: $(PCCMIP)/pcc_node.h
xdefs.ln: ../src/machdep.h
xdefs.ln: $(PCCMIP)/pcc_types.h
xdefs.ln: ./symtab.h
xdefs.ln: $(PCCMIP)/pcc_symtab.h
scan.o: $(MIP)/scan.c
scan.o: /usr/include/ctype.h
scan.o: $(MIP)/cpass1.h
scan.o: ../src/machdep.h
scan.o: ./align.h
scan.o: $(MIP)/mip.h
scan.o: /usr/include/stdio.h
scan.o: ./ops.h
scan.o: $(PCCMIP)/pcc_ops.h
scan.o: ./types.h
scan.o: $(PCCMIP)/pcc_types.h
scan.o: ./node.h
scan.o: $(PCCMIP)/pcc_node.h
scan.o: ../src/machdep.h
scan.o: $(PCCMIP)/pcc_types.h
scan.o: ./symtab.h
scan.o: $(PCCMIP)/pcc_symtab.h
scan.o: $(MIP)/messages.h
scan.o: /usr/include/a.out.h
scan.o: /usr/include/sys/exec.h
scan.o: /usr/include/stab.h
scan.ln: $(MIP)/scan.c
scan.ln: /usr/include/ctype.h
scan.ln: $(MIP)/cpass1.h
scan.ln: ../src/machdep.h
scan.ln: ./align.h
scan.ln: $(MIP)/mip.h
scan.ln: /usr/include/stdio.h
scan.ln: ./ops.h
scan.ln: $(PCCMIP)/pcc_ops.h
scan.ln: ./types.h
scan.ln: $(PCCMIP)/pcc_types.h
scan.ln: ./node.h
scan.ln: $(PCCMIP)/pcc_node.h
scan.ln: ../src/machdep.h
scan.ln: $(PCCMIP)/pcc_types.h
scan.ln: ./symtab.h
scan.ln: $(PCCMIP)/pcc_symtab.h
scan.ln: $(MIP)/messages.h
scan.ln: /usr/include/a.out.h
scan.ln: /usr/include/sys/exec.h
scan.ln: /usr/include/stab.h
pftn.o: $(MIP)/pftn.c
pftn.o: $(MIP)/cpass1.h
pftn.o: ../src/machdep.h
pftn.o: ./align.h
pftn.o: $(MIP)/mip.h
pftn.o: /usr/include/stdio.h
pftn.o: ./ops.h
pftn.o: $(PCCMIP)/pcc_ops.h
pftn.o: ./types.h
pftn.o: $(PCCMIP)/pcc_types.h
pftn.o: ./node.h
pftn.o: $(PCCMIP)/pcc_node.h
pftn.o: ../src/machdep.h
pftn.o: $(PCCMIP)/pcc_types.h
pftn.o: ./symtab.h
pftn.o: $(PCCMIP)/pcc_symtab.h
pftn.o: $(MIP)/messages.h
pftn.ln: $(MIP)/pftn.c
pftn.ln: $(MIP)/cpass1.h
pftn.ln: ../src/machdep.h
pftn.ln: ./align.h
pftn.ln: $(MIP)/mip.h
pftn.ln: /usr/include/stdio.h
pftn.ln: ./ops.h
pftn.ln: $(PCCMIP)/pcc_ops.h
pftn.ln: ./types.h
pftn.ln: $(PCCMIP)/pcc_types.h
pftn.ln: ./node.h
pftn.ln: $(PCCMIP)/pcc_node.h
pftn.ln: ../src/machdep.h
pftn.ln: $(PCCMIP)/pcc_types.h
pftn.ln: ./symtab.h
pftn.ln: $(PCCMIP)/pcc_symtab.h
pftn.ln: $(MIP)/messages.h
trees.o: $(MIP)/trees.c
trees.o: $(MIP)/cpass1.h
trees.o: ../src/machdep.h
trees.o: ./align.h
trees.o: $(MIP)/mip.h
trees.o: /usr/include/stdio.h
trees.o: ./ops.h
trees.o: $(PCCMIP)/pcc_ops.h
trees.o: ./types.h
trees.o: $(PCCMIP)/pcc_types.h
trees.o: ./node.h
trees.o: $(PCCMIP)/pcc_node.h
trees.o: ../src/machdep.h
trees.o: $(PCCMIP)/pcc_types.h
trees.o: ./symtab.h
trees.o: $(PCCMIP)/pcc_symtab.h
trees.o: $(MIP)/messages.h
trees.ln: $(MIP)/trees.c
trees.ln: $(MIP)/cpass1.h
trees.ln: ../src/machdep.h
trees.ln: ./align.h
trees.ln: $(MIP)/mip.h
trees.ln: /usr/include/stdio.h
trees.ln: ./ops.h
trees.ln: $(PCCMIP)/pcc_ops.h
trees.ln: ./types.h
trees.ln: $(PCCMIP)/pcc_types.h
trees.ln: ./node.h
trees.ln: $(PCCMIP)/pcc_node.h
trees.ln: ../src/machdep.h
trees.ln: $(PCCMIP)/pcc_types.h
trees.ln: ./symtab.h
trees.ln: $(PCCMIP)/pcc_symtab.h
trees.ln: $(MIP)/messages.h
optim.o: $(MIP)/optim.c
optim.o: $(MIP)/cpass1.h
optim.o: ../src/machdep.h
optim.o: ./align.h
optim.o: $(MIP)/mip.h
optim.o: /usr/include/stdio.h
optim.o: ./ops.h
optim.o: $(PCCMIP)/pcc_ops.h
optim.o: ./types.h
optim.o: $(PCCMIP)/pcc_types.h
optim.o: ./node.h
optim.o: $(PCCMIP)/pcc_node.h
optim.o: ../src/machdep.h
optim.o: $(PCCMIP)/pcc_types.h
optim.o: ./symtab.h
optim.o: $(PCCMIP)/pcc_symtab.h
optim.ln: $(MIP)/optim.c
optim.ln: $(MIP)/cpass1.h
optim.ln: ../src/machdep.h
optim.ln: ./align.h
optim.ln: $(MIP)/mip.h
optim.ln: /usr/include/stdio.h
optim.ln: ./ops.h
optim.ln: $(PCCMIP)/pcc_ops.h
optim.ln: ./types.h
optim.ln: $(PCCMIP)/pcc_types.h
optim.ln: ./node.h
optim.ln: $(PCCMIP)/pcc_node.h
optim.ln: ../src/machdep.h
optim.ln: $(PCCMIP)/pcc_types.h
optim.ln: ./symtab.h
optim.ln: $(PCCMIP)/pcc_symtab.h
yyerror.o: $(MIP)/yyerror.c
yyerror.o: $(MIP)/cpass1.h
yyerror.o: ../src/machdep.h
yyerror.o: ./align.h
yyerror.o: $(MIP)/mip.h
yyerror.o: /usr/include/stdio.h
yyerror.o: ./ops.h
yyerror.o: $(PCCMIP)/pcc_ops.h
yyerror.o: ./types.h
yyerror.o: $(PCCMIP)/pcc_types.h
yyerror.o: ./node.h
yyerror.o: $(PCCMIP)/pcc_node.h
yyerror.o: ../src/machdep.h
yyerror.o: $(PCCMIP)/pcc_types.h
yyerror.o: ./symtab.h
yyerror.o: $(PCCMIP)/pcc_symtab.h
yyerror.o: /usr/include/ctype.h
yyerror.ln: $(MIP)/yyerror.c
yyerror.ln: $(MIP)/cpass1.h
yyerror.ln: ../src/machdep.h
yyerror.ln: ./align.h
yyerror.ln: $(MIP)/mip.h
yyerror.ln: /usr/include/stdio.h
yyerror.ln: ./ops.h
yyerror.ln: $(PCCMIP)/pcc_ops.h
yyerror.ln: ./types.h
yyerror.ln: $(PCCMIP)/pcc_types.h
yyerror.ln: ./node.h
yyerror.ln: $(PCCMIP)/pcc_node.h
yyerror.ln: ../src/machdep.h
yyerror.ln: $(PCCMIP)/pcc_types.h
yyerror.ln: ./symtab.h
yyerror.ln: $(PCCMIP)/pcc_symtab.h
yyerror.ln: /usr/include/ctype.h
messages.o: $(MIP)/messages.c
messages.o: $(MIP)/messages.h
messages.ln: $(MIP)/messages.c
messages.ln: $(MIP)/messages.h
lerror.o: ../src/lerror.c
lerror.o: /usr/include/stdio.h
lerror.o: $(MIP)/messages.h
lerror.o: ../src/lerror.h
lerror.o: /usr/include/signal.h
lerror.ln: ../src/lerror.c
lerror.ln: /usr/include/stdio.h
lerror.ln: $(MIP)/messages.h
lerror.ln: ../src/lerror.h
lerror.ln: /usr/include/signal.h
msgbuf.o: ../src/msgbuf.c
msgbuf.o: $(MIP)/messages.h
msgbuf.o: ../src/lerror.h
msgbuf.ln: ../src/msgbuf.c
msgbuf.ln: $(MIP)/messages.h
msgbuf.ln: ../src/lerror.h
lint.o: ../src/lint.c
lint.o: $(MIP)/cpass1.h
lint.o: ../src/machdep.h
lint.o: ./align.h
lint.o: $(MIP)/mip.h
lint.o: /usr/include/stdio.h
lint.o: ./ops.h
lint.o: $(PCCMIP)/pcc_ops.h
lint.o: ./types.h
lint.o: $(PCCMIP)/pcc_types.h
lint.o: ./node.h
lint.o: $(PCCMIP)/pcc_node.h
lint.o: ../src/machdep.h
lint.o: $(PCCMIP)/pcc_types.h
lint.o: ./symtab.h
lint.o: $(PCCMIP)/pcc_symtab.h
lint.o: $(MIP)/messages.h
lint.o: ../src/lerror.h
lint.o: ../src/lmanifest
lint.o: /usr/include/ctype.h
lint.o: /usr/include/signal.h
lint.ln: ../src/lint.c
lint.ln: $(MIP)/cpass1.h
lint.ln: ../src/machdep.h
lint.ln: ./align.h
lint.ln: $(MIP)/mip.h
lint.ln: /usr/include/stdio.h
lint.ln: ./ops.h
lint.ln: $(PCCMIP)/pcc_ops.h
lint.ln: ./types.h
lint.ln: $(PCCMIP)/pcc_types.h
lint.ln: ./node.h
lint.ln: $(PCCMIP)/pcc_node.h
lint.ln: ../src/machdep.h
lint.ln: $(PCCMIP)/pcc_types.h
lint.ln: ./symtab.h
lint.ln: $(PCCMIP)/pcc_symtab.h
lint.ln: $(MIP)/messages.h
lint.ln: ../src/lerror.h
lint.ln: ../src/lmanifest
lint.ln: /usr/include/ctype.h
lint.ln: /usr/include/signal.h
hash.o: ../src/hash.c
hash.ln: ../src/hash.c
cgram.o: cgram.c
cgram.o: $(MIP)/cpass1.h
cgram.o: ../src/machdep.h
cgram.o: ./align.h
cgram.o: $(MIP)/mip.h
cgram.o: /usr/include/stdio.h
cgram.o: ./ops.h
cgram.o: $(PCCMIP)/pcc_ops.h
cgram.o: ./types.h
cgram.o: $(PCCMIP)/pcc_types.h
cgram.o: ./node.h
cgram.o: $(PCCMIP)/pcc_node.h
cgram.o: ../src/machdep.h
cgram.o: $(PCCMIP)/pcc_types.h
cgram.o: ./symtab.h
cgram.o: $(PCCMIP)/pcc_symtab.h
cgram.o: ./sw.h
cgram.o: $(PCCMIP)/pcc_sw.h
cgram.o: $(MIP)/messages.h
cgram.ln: cgram.c
cgram.ln: $(MIP)/cpass1.h
cgram.ln: ../src/machdep.h
cgram.ln: ./align.h
cgram.ln: $(MIP)/mip.h
cgram.ln: /usr/include/stdio.h
cgram.ln: ./ops.h
cgram.ln: $(PCCMIP)/pcc_ops.h
cgram.ln: ./types.h
cgram.ln: $(PCCMIP)/pcc_types.h
cgram.ln: ./node.h
cgram.ln: $(PCCMIP)/pcc_node.h
cgram.ln: ../src/machdep.h
cgram.ln: $(PCCMIP)/pcc_types.h
cgram.ln: ./symtab.h
cgram.ln: $(PCCMIP)/pcc_symtab.h
cgram.ln: ./sw.h
cgram.ln: $(PCCMIP)/pcc_sw.h
cgram.ln: $(MIP)/messages.h
rodata.o: rodata.c
rodata.ln: rodata.c
lpass2.o: ../src/lpass2.c
lpass2.o: /usr/include/stdio.h
lpass2.o: ./types.h
lpass2.o: $(PCCMIP)/pcc_types.h
lpass2.o: ../src/lerror.h
lpass2.o: ../src/lmanifest
lpass2.o: ../src/lpass2.h
lpass2.o: /usr/include/ctype.h
lpass2.ln: ../src/lpass2.c
lpass2.ln: /usr/include/stdio.h
lpass2.ln: ./types.h
lpass2.ln: $(PCCMIP)/pcc_types.h
lpass2.ln: ../src/lerror.h
lpass2.ln: ../src/lmanifest
lpass2.ln: ../src/lpass2.h
lpass2.ln: /usr/include/ctype.h
lerror2.o: ../src/lerror2.c
lerror2.o: /usr/include/stdio.h
lerror2.o: ../src/lerror.h
lerror2.o: $(MIP)/mip.h
lerror2.o: /usr/include/stdio.h
lerror2.o: ./ops.h
lerror2.o: $(PCCMIP)/pcc_ops.h
lerror2.o: ./types.h
lerror2.o: $(PCCMIP)/pcc_types.h
lerror2.o: ./node.h
lerror2.o: $(PCCMIP)/pcc_node.h
lerror2.o: ../src/machdep.h
lerror2.o: ./align.h
lerror2.o: $(PCCMIP)/pcc_types.h
lerror2.o: ../src/lmanifest
lerror2.o: ../src/lpass2.h
lerror2.o: $(MIP)/messages.h
lerror2.o: /usr/include/signal.h
lerror2.o: /usr/include/ctype.h
lerror2.ln: ../src/lerror2.c
lerror2.ln: /usr/include/stdio.h
lerror2.ln: ../src/lerror.h
lerror2.ln: $(MIP)/mip.h
lerror2.ln: /usr/include/stdio.h
lerror2.ln: ./ops.h
lerror2.ln: $(PCCMIP)/pcc_ops.h
lerror2.ln: ./types.h
lerror2.ln: $(PCCMIP)/pcc_types.h
lerror2.ln: ./node.h
lerror2.ln: $(PCCMIP)/pcc_node.h
lerror2.ln: ../src/machdep.h
lerror2.ln: ./align.h
lerror2.ln: $(PCCMIP)/pcc_types.h
lerror2.ln: ../src/lmanifest
lerror2.ln: ../src/lpass2.h
lerror2.ln: $(MIP)/messages.h
lerror2.ln: /usr/include/signal.h
lerror2.ln: /usr/include/ctype.h
msgbuf2.o: ../src/msgbuf2.c
msgbuf2.o: ../src/lerror.h
msgbuf2.ln: ../src/msgbuf2.c
msgbuf2.ln: ../src/lerror.h
comm1.o: $(MIP)/common.c
comm1.o: $(MIP)/cpass1.h
comm1.o: ../src/machdep.h
comm1.o: ./align.h
comm1.o: $(MIP)/mip.h
comm1.o: /usr/include/stdio.h
comm1.o: ./ops.h
comm1.o: $(PCCMIP)/pcc_ops.h
comm1.o: ./types.h
comm1.o: $(PCCMIP)/pcc_types.h
comm1.o: ./node.h
comm1.o: $(PCCMIP)/pcc_node.h
comm1.o: ../src/machdep.h
comm1.o: $(PCCMIP)/pcc_types.h
comm1.o: ./symtab.h
comm1.o: $(PCCMIP)/pcc_symtab.h
comm1.ln: $(MIP)/common.c
comm1.ln: $(MIP)/cpass1.h
comm1.ln: ../src/machdep.h
comm1.ln: ./align.h
comm1.ln: $(MIP)/mip.h
comm1.ln: /usr/include/stdio.h
comm1.ln: ./ops.h
comm1.ln: $(PCCMIP)/pcc_ops.h
comm1.ln: ./types.h
comm1.ln: $(PCCMIP)/pcc_types.h
comm1.ln: ./node.h
comm1.ln: $(PCCMIP)/pcc_node.h
comm1.ln: ../src/machdep.h
comm1.ln: $(PCCMIP)/pcc_types.h
comm1.ln: ./symtab.h
comm1.ln: $(PCCMIP)/pcc_symtab.h
# DEPENDENCIES MUST END AT END OF FILE
# IF YOU PUT STUFF HERE IT WILL GO AWAY
# see make depend above

57
5bin/lint/sparc/align.h Normal file
View File

@@ -0,0 +1,57 @@
/* @(#)align.h 1.1 92/07/30 SMI */
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
/*
* Storage alignment parameters for sparc compilers.
* In "lint", we can't #define SZCHAR, and the like, because they
* are variables (since if "-p" is specified values are chosen that
* will cause as many errors to be caught as possible).
*/
# ifndef _align_
# define _align_ 1
# define _SZCHAR 8
# define _SZINT 32
# define _SZFLOAT 32
# define _SZDOUBLE 64
# define _SZLONG 32
# define _SZSHORT 16
# define _SZPOINT 32
# define _ALCHAR 8
# define _ALINT 32
# define _ALFLOAT 32
# define _ALDOUBLE 64
# define _ALLONG 32
# define _ALSHORT 16
# define _ALPOINT 32
# define _ALSTRUCT 8
# define _ALSTACK 64
#ifndef LINT
# define SZCHAR _SZCHAR
# define SZINT _SZINT
# define SZFLOAT _SZFLOAT
# define SZDOUBLE _SZDOUBLE
# define SZEXTENDED _SZEXTENDED
# define SZLONG _SZLONG
# define SZSHORT _SZSHORT
# define SZPOINT _SZPOINT
# define ALCHAR _ALCHAR
# define ALINT _ALINT
# define ALFLOAT _ALFLOAT
# define ALDOUBLE _ALDOUBLE
# define ALEXTENDED _ALEXTENDED
# define ALLONG _ALLONG
# define ALSHORT _ALSHORT
# define ALPOINT _ALPOINT
# define ALSTRUCT _ALSTRUCT
# define ALSTACK _ALSTACK
#endif
# endif _align_

155
5bin/ln.c Normal file
View File

@@ -0,0 +1,155 @@
#ifndef lint
static char sccsid[] = "@(#)ln.c 1.1 92/07/30 SMI"; /* from UCB 4.6 11/15/85 */
#endif
/*
* ln
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <errno.h>
struct stat stb;
int Fflag; /* force a hard link to a directory? */
int fflag; /* no questions asked */
int sflag; /* symbolic link */
char *rindex();
extern int errno;
main(argc, argv)
int argc;
register char **argv;
{
register int i, r;
extern int optind;
int c;
while ((c = getopt(argc, argv, "Ffs")) != EOF) {
switch(c) {
case 'F':
Fflag++;
break;
case 'f':
fflag++;
break;
case 's':
sflag++;
break;
case '?':
default:
goto usage;
}
}
argc -= optind;
argv = &argv[optind];
if (argc == 0)
goto usage;
else if (argc == 1) {
argv[argc] = ".";
argc++;
}
if (argc > 2) {
if (stat(argv[argc-1], &stb) < 0)
goto usage;
if ((stb.st_mode&S_IFMT) != S_IFDIR)
goto usage;
}
r = 0;
for(i = 0; i < argc-1; i++)
r |= linkit(argv[i], argv[argc-1]);
exit(r);
usage:
(void) fprintf(stderr,
"Usage: ln [-F] [-f] [-s] f1 or ln [-F] [-f] [-s] f1 f2 or ln [-s] f1 ... fn d1\n");
exit(1);
/* NOTREACHED */
}
int link(), symlink();
linkit(from, to)
char *from, *to;
{
char destname[MAXPATHLEN + 1];
char *tail;
struct stat stb2;
int (*linkf)() = sflag ? symlink : link;
if (stat(from, &stb) < 0 && !sflag){
fprintf(stderr,"ln: cannot access %s\n", from);
return(1);
}
/* is source a directory? */
if (sflag == 0 && Fflag == 0 && (stb.st_mode&S_IFMT) == S_IFDIR) {
fprintf(stderr,"ln: %s is a directory\n", from);
return (1);
}
if ((stat(to, &stb2) >= 0) && (stb2.st_mode&S_IFMT) == S_IFDIR) {
tail = rindex(from, '/');
if (tail == 0)
tail = from;
else
tail++;
if (strlen(to) + strlen(tail) >= sizeof destname - 1) {
(void) fprintf(stderr,
"ln: %s/%s: Name too long\n", to, tail);
return (1);
}
(void) sprintf(destname, "%s/%s", to, tail);
to = destname;
}
if (stat(to, &stb2) >=0) {
/* if filenames and inodes are the same, it's an error */
if (stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino) {
fprintf(stderr,"ln: %s and %s are identical\n",from, to);
return (1);
}
/* if the user doesn't have access to the file, ask him */
if (access(to, W_OK) < 0 && isatty(fileno(stdin)) && !fflag) {
printf("ln: override protection %o for %s? ",
stb2.st_mode&0777, to);
if (!yes())
return(1);
}
if (unlink(to) < 0) {
fprintf(stderr,"ln: cannot unlink %s\n", to);
return(1);
}
}
if ((*linkf)(from, to) < 0) {
if (errno == EEXIST || sflag)
Perror(to);
else if (access(from, 0) < 0)
Perror(from);
else
Perror(to);
return (1);
}
return (0);
}
Perror(s)
char *s;
{
(void) fprintf(stderr, "ln: ");
perror(s);
}
/*
* Get a yes/no answer from the user.
*/
yes()
{
int i, b;
i = b = getchar();
while (b != '\n' && b != EOF)
b = getchar();
return (i == 'y');
}

991
5bin/ls.c Normal file
View File

@@ -0,0 +1,991 @@
#ifndef lint
static char sccsid[] = "@(#)ls.c 1.1 92/07/30 SMI"; /* from S5R2 1.19 */
#endif
/*
* list file or directory;
* define DOTSUP to suppress listing of files beginning with dot
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <stdio.h>
#if u3b
#include <sys/macro.h>
#endif
#include <ctype.h>
#include <locale.h>
#ifndef STANDALONE
#define TERMINFO
#endif
/* -DNOTERMINFO can be defined on the cc command line to prevent
* the use of terminfo. This should be done on systems not having
* the terminfo feature (pre 6.0 sytems ?).
* As a result, columnar listings assume 80 columns for output,
* unless told otherwise via the COLUMNS environment variable.
*/
#ifdef NOTERMINFO
#undef TERMINFO
#endif
#ifdef TERMINFO
#include <curses.h>
#include <term.h>
#endif
#define DOTSUP 1
#define ISARG 0100000 /* this bit equals 1 in lflags of structure lbuf
* if name is an argument to ls;
*/
#define DIRECT 10 /* Number of direct blocks */
struct lbuf {
char ltype; /* file type, e.g. 'd', 'c', 'f' */
ino_t lnum; /* inode number of file */
short lflags; /* 0777 bits used as r,w,x permissions */
short lnl; /* number of links to file */
unsigned short luid; /* owner id */
unsigned short lgid; /* group id */
long lsize; /* file size or major/minor dev numbers */
long lblks; /* number of blocks used */
long lmtime; /* time (modify or access or create) */
char *lname; /* for filename in directory or name in ls-command */
char *llinkto; /* symbolic link value */
};
struct dchain {
char *dc_name; /* path name */
struct dchain *dc_next; /* next directory in the chain */
};
struct dchain *dfirst; /* start of the dir chain */
struct dchain *cdfirst; /* start of the durrent dir chain */
struct dchain *dtemp; /* temporary - used for linking */
char *curdir; /* the current directory */
int nfiles = 0; /* number of flist entries in current use */
int nargs = 0; /* number of flist entries used for arguments */
int maxfils = 0; /* number of flist/lbuf entries allocated */
int maxn = 0; /* number of flist entries with lbufs assigned */
int quantn = 1024; /* allocation growth quantum */
struct lbuf *nxtlbf; /* pointer to next lbuf to be assigned */
struct lbuf **flist; /* pointer to list of lbuf pointers */
struct lbuf *gstat();
FILE *pwdfu, *pwdfg;
int aflg, bflg, cflg, dflg, fflg, gflg, iflg, lflg, mflg;
int nflg, oflg, pflg, qflg, sflg, tflg, uflg, xflg;
int Cflg, Fflg, Lflg, Rflg;
int rflg = 1; /* initialized to 1 for special use in compar() */
int flags;
int err = 0; /* Contains return code */
char *dmark; /* Used if -p option active. Contains "/" or NULL. */
unsigned lastuid = -1, lastgid = -1;
int statreq; /* is > 0 if any of sflg, (n)lflg, tflg are on */
static int nomocore = 0;
char *dotp = ".";
char *makename();
char *getname(), *getgroup();
char *ctime(), *strcpy();
long tblocks; /* total number of blocks of files in a directory */
long year, now;
int num_cols = 80;
int colwidth;
int filewidth;
int fixedwidth;
int curcol;
int compar();
main(argc, argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind;
int amino, opterr=0;
int c;
register struct lbuf *ep;
struct lbuf lb;
int i, width;
long time();
char *malloc();
void qsort(), exit();
#ifdef STANDALONE
if (argv[0][0] == '\0')
argc = getargv("ls", &argv, 0);
#endif
setlocale(LC_ALL, ""); /* get local environment */
lb.lmtime = time((long *) NULL);
year = lb.lmtime - 6L*30L*24L*60L*60L; /* 6 months ago */
now = lb.lmtime + 60;
while ((c=getopt(argc, argv,
"RadCxmnlogrtucpFbqisfL")) != EOF) switch(c) {
case 'R':
Rflg++;
statreq++;
continue;
case 'a':
aflg++;
continue;
case 'd':
dflg++;
continue;
case 'C':
Cflg = 1;
mflg = 0;
continue;
case 'x':
xflg = 1;
Cflg = 1;
mflg = 0;
continue;
case 'm':
Cflg = 0;
mflg = 1;
continue;
case 'n':
nflg++;
case 'l':
lflg++;
statreq++;
continue;
case 'o':
oflg++;
lflg++;
statreq++;
continue;
case 'g':
gflg++;
lflg++;
statreq++;
continue;
case 'r':
rflg = -1;
continue;
case 't':
tflg++;
statreq++;
continue;
case 'u':
uflg++;
continue;
case 'c':
cflg++;
continue;
case 'p':
pflg++;
statreq++;
continue;
case 'F':
Fflg++;
statreq++;
continue;
case 'b':
bflg = 1;
qflg = 0;
continue;
case 'q':
qflg = 1;
bflg = 0;
continue;
case 'i':
iflg++;
continue;
case 's':
sflg++;
statreq++;
continue;
case 'f':
fflg++;
continue;
case 'L':
Lflg++;
continue;
case '?':
opterr++;
continue;
}
if(opterr) {
fprintf(stderr,"usage: ls -RadCxmnlogrtucpFbqisfL [files]\n");
exit(2);
}
if (fflg) {
aflg++;
lflg = 0;
sflg = 0;
tflg = 0;
statreq = 0;
}
fixedwidth = 2;
if (pflg || Fflg)
fixedwidth++;
if (iflg)
fixedwidth += 6;
if (sflg)
fixedwidth += 5;
if (lflg) { /* This is the way */
if (!gflg && !oflg) /* 5.0 behaved, but */
gflg = oflg = 1; /* it may be open */
else /* to interpretation*/
if (gflg && oflg)
gflg = oflg = 0;
Cflg = mflg = 0;
}
if (Cflg || mflg) {
char *getenv();
char *clptr;
if ((clptr = getenv("COLUMNS")) != NULL)
num_cols = atoi(clptr);
#ifdef TERMINFO
else {
setupterm(0,1,&i); /* get term description */
resetterm(); /* undo what setupterm changed */
if (i == 1)
num_cols = columns;
}
#endif
if (num_cols < 20 || num_cols > 160)
/* assume it is an error */
num_cols = 80;
}
/* allocate space for flist and the associated */
/* data structures (lbufs) */
maxfils = quantn;
if((flist=(struct lbuf **)malloc((unsigned)(maxfils * sizeof(struct lbuf *)))) == NULL
|| (nxtlbf = (struct lbuf *)malloc((unsigned)(quantn * sizeof(struct lbuf)))) == NULL) {
fprintf(stderr, "ls: out of memory\n");
exit(2);
}
if ((amino=(argc-optind))==0) { /* case when no names are given
* in ls-command and current
* directory is to be used
*/
argv[optind] = dotp;
}
for (i=0; i < (amino ? amino : 1); i++) {
if (Cflg || mflg) {
width = strlen(argv[optind]);
if (width > filewidth)
filewidth = width;
}
if ((ep = gstat((*argv[optind] ? argv[optind] : dotp), 1))==NULL)
{
err = 2;
optind++;
continue;
}
ep->lname = (*argv[optind] ? argv[optind] : dotp);
ep->lflags |= ISARG;
optind++;
nargs++; /* count good arguments stored in flist */
}
colwidth = fixedwidth + filewidth;
qsort(flist, (unsigned)nargs, sizeof(struct lbuf *), compar);
for (i=0; i<nargs; i++)
if (flist[i]->ltype=='d' && dflg==0 || fflg)
break;
pem(&flist[0],&flist[i], 0);
for (; i<nargs; i++) {
pdirectory(flist[i]->lname, (amino>1), nargs);
/* -R: print subdirectories found */
while (dfirst || cdfirst) {
/* Place direct subdirs on front in right order */
while (cdfirst) {
/* reverse cdfirst onto front of dfirst */
dtemp = cdfirst;
cdfirst = cdfirst -> dc_next;
dtemp -> dc_next = dfirst;
dfirst = dtemp;
}
/* take off first dir on dfirst & print it */
dtemp = dfirst;
dfirst = dfirst->dc_next;
pdirectory (dtemp->dc_name, 1, nargs);
free (dtemp->dc_name);
free ((char *)dtemp);
}
}
exit(err);
/*NOTREACHED*/
}
/*
* pdirectory: print the directory name, labelling it if title is
* nonzero, using lp as the place to start reading in the dir.
*/
pdirectory (name, title, lp)
char *name;
int title;
int lp;
{
register struct dchain *dp;
register struct lbuf *ap;
register char *pname;
register int j;
filewidth = 0;
curdir = name;
if (title) {
putc('\n', stdout);
pprintf(name);
putc(':', stdout);
curcol++;
new_line();
}
nfiles = lp;
rddir(name);
if (fflg==0)
qsort(&flist[lp],(unsigned)(nfiles - lp),sizeof(struct lbuf *),compar);
if (Rflg) for (j = nfiles - 1; j >= lp; j--) {
ap = flist[j];
if (ap->ltype == 'd' && strcmp(ap->lname, ".") &&
strcmp(ap->lname, "..")) {
dp = (struct dchain *)calloc(1,sizeof(struct dchain));
if (dp == NULL)
fprintf(stderr,"ls: out of memory\n");
pname = makename(curdir, ap->lname);
dp->dc_name = (char *)calloc(1,strlen(pname)+1);
if (dp->dc_name == NULL) {
fprintf(stderr,"ls: out of memory\n");
free(dp);
}
else {
strcpy(dp->dc_name, pname);
dp -> dc_next = dfirst;
dfirst = dp;
}
}
}
if (lflg || sflg)
curcol += printf("total %ld", tblocks);
pem(&flist[lp],&flist[nfiles],lflg||sflg);
}
/*
* pem: print 'em. Print a list of files (e.g. a directory) bounded
* by slp and lp.
*/
pem(slp, lp, tot_flag)
register struct lbuf **slp, **lp;
int tot_flag;
{
int ncols, nrows, row, col;
register struct lbuf **ep;
if (Cflg || mflg)
ncols = num_cols / colwidth;
if (ncols == 1 || mflg || xflg || !Cflg) {
for (ep = slp; ep < lp; ep++)
pentry(*ep);
new_line();
return;
}
/* otherwise print -C columns */
if (tot_flag)
slp--;
nrows = (lp - slp - 1) / ncols + 1;
for (row = 0; row < nrows; row++) {
col = (row == 0 && tot_flag);
for (; col < ncols; col++) {
ep = slp + (nrows * col) + row;
if (ep < lp)
pentry(*ep);
}
new_line();
}
}
pentry(ap) /* print one output entry;
* if uid/gid is not found in the appropriate
* file (passwd/group), then print uid/gid instead of
* user/group name;
*/
struct lbuf *ap;
{
struct {
char dminor,
dmajor;
};
register struct lbuf *p;
register char *cp;
p = ap;
column();
if (iflg)
if (mflg && !lflg)
curcol += printf("%u ", p->lnum);
else
curcol += printf("%5u ", p->lnum);
if (sflg)
curcol += printf( (mflg && !lflg) ? "%ld " : "%4ld " ,
(p->ltype != 'b' && p->ltype != 'c') ?
p->lblks : 0L );
if (lflg) {
putchar(p->ltype);
curcol++;
pmode(p->lflags);
curcol += printf("%4d ", p->lnl);
if (oflg)
if(!nflg && (cp = getname(p->luid))!=NULL)
curcol += printf("%-9.9s", cp);
else
curcol += printf("%-9u", p->luid);
if (gflg)
if(!nflg && (cp = getgroup(p->lgid))!=NULL)
curcol += printf("%-9.9s", cp);
else
curcol += printf("%-9u", p->lgid);
if (p->ltype=='b' || p->ltype=='c')
curcol += printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize));
else
curcol += printf("%7ld", p->lsize);
cp = ctime(&p->lmtime);
if((p->lmtime < year) || (p->lmtime > now))
curcol += printf(" %-7.7s %-4.4s ", cp+4, cp+20);
else
curcol += printf(" %-12.12s ", cp+4);
}
if (qflg || bflg)
pprintf(p->lname);
else
curcol += printf("%s",p->lname);
if (lflg && p->llinkto) {
curcol += printf(" -> ");
if (qflg || bflg)
pprintf(p->llinkto);
else
curcol += printf("%s", p->llinkto);
} else if (pflg) {
if (p->ltype == 'd') {
putc('/', stdout);
curcol++;
}
} else if (Fflg) {
if (p->ltype == 'd') {
putc('/', stdout);
curcol++;
} else if (p->ltype == 'l') {
putc('@', stdout);
curcol++;
} else if (p->ltype == 's') {
putc('=', stdout);
curcol++;
} else if (p->lflags & 0111) {
putc('*', stdout);
curcol++;
}
}
}
/* print various r,w,x permissions
*/
pmode(aflag)
{
/* these arrays are declared static to allow initializations */
static int m0[] = { 1, S_IREAD>>0, 'r', '-' };
static int m1[] = { 1, S_IWRITE>>0, 'w', '-' };
static int m2[] = { 3, S_ISUID|S_IEXEC, 's', S_IEXEC, 'x', S_ISUID, 'S', '-' };
static int m3[] = { 1, S_IREAD>>3, 'r', '-' };
static int m4[] = { 1, S_IWRITE>>3, 'w', '-' };
static int m5[] = { 3, S_ISGID|(S_IEXEC>>3),'s', S_IEXEC>>3,'x', S_ISGID,'S', '-'};
static int m6[] = { 1, S_IREAD>>6, 'r', '-' };
static int m7[] = { 1, S_IWRITE>>6, 'w', '-' };
static int m8[] = { 3, S_ISVTX|(S_IEXEC>>6),'t', S_IEXEC>>6,'x', S_ISVTX,'T', '-'};
static int *m[] = { m0, m1, m2, m3, m4, m5, m6, m7, m8};
register int **mp;
flags = aflag;
for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)
selectbits(*mp++);
}
selectbits(pairp)
register int *pairp;
{
register int n;
n = *pairp++;
while (n-->0) {
if((flags & *pairp) == *pairp) {
pairp++;
break;
}else {
pairp += 2;
}
}
putchar(*pairp);
curcol++;
}
/*
* column: get to the beginning of the next column.
*/
column()
{
if (curcol == 0)
return;
if (mflg) {
putc(',', stdout);
curcol++;
if (curcol + colwidth + 2 > num_cols) {
putc('\n', stdout);
curcol = 0;
return;
}
putc(' ', stdout);
curcol++;
return;
}
if (Cflg == 0) {
putc('\n', stdout);
curcol = 0;
return;
}
if ((curcol / colwidth + 2) * colwidth > num_cols) {
putc('\n', stdout);
curcol = 0;
return;
}
do {
putc(' ', stdout);
curcol++;
} while (curcol % colwidth);
}
new_line()
{
if (curcol) {
putc('\n',stdout);
curcol = 0;
}
}
/* read each filename in directory dir and store its
* status in flist[nfiles]
* use makename() to form pathname dir/filename;
*/
rddir(dir)
char *dir;
{
struct direct *dentry;
DIR *dirf;
extern char *malloc();
register struct lbuf *ep;
register int width;
if ((dirf = opendir(dir)) == NULL) {
fflush(stdout);
fprintf(stderr, "ls: ");
perror(dir);
err = 2;
return;
}
else {
tblocks = 0;
while (dentry = readdir(dirf)) {
if (aflg==0 && dentry->d_name[0]=='.'
# ifndef DOTSUP
&& (dentry->d_name[1]=='\0' || dentry->d_name[1]=='.'
&& dentry->d_name[2]=='\0')
# endif
) /* check for directory items '.', '..' */
continue;
if (Cflg || mflg) {
width = strlen(dentry->d_name);
if (width > filewidth)
filewidth = width;
}
ep = gstat(makename(dir, dentry->d_name), 0);
if (ep==NULL)
continue;
else {
ep->lnum = dentry->d_ino;
ep->lname = malloc(dentry->d_namlen + 1);
if (ep->lname==NULL) {
fflush(stdout);
fprintf(stderr, "ls: out of memory\n");
err = 2;
nomocore = 1;
break;
}
strcpy(ep->lname, dentry->d_name);
}
}
closedir(dirf);
colwidth = fixedwidth + filewidth;
}
}
/* get status of file and recomputes tblocks;
* argfl = 1 if file is a name in ls-command and = 0
* for filename in a directory whose name is an
* argument in the command;
* stores a pointer in flist[nfiles] and
* returns that pointer;
* returns NULL if failed;
*/
struct lbuf *
gstat(file, argfl)
char *file;
{
extern int stat(), lstat();
int (*statf)() = Lflg ? stat : lstat;
struct stat statb, statb1;
register struct lbuf *rep;
char buf[MAXPATHLEN + 2];
register int cc;
char *malloc(), *realloc();
if (nomocore)
return(NULL);
else if (nfiles >= maxfils) {
/* all flist/lbuf pair assigned files time to get some more space */
maxfils += quantn;
if((flist=(struct lbuf **)realloc((char *)flist, (unsigned)(maxfils * sizeof(struct lbuf *)))) == NULL
|| (nxtlbf = (struct lbuf *)malloc((unsigned)(quantn * sizeof(struct lbuf)))) == NULL) {
fprintf(stderr, "ls: out of memory\n");
nomocore = 1;
return(NULL);
}
}
/* nfiles is reset to nargs for each directory
* that is given as an argument maxn is checked
* to prevent the assignment of an lbuf to a flist entry
* that already has one assigned.
*/
if(nfiles >= maxn) {
rep = nxtlbf++;
flist[nfiles++] = rep;
maxn = nfiles;
}else {
rep = flist[nfiles++];
}
rep->lflags = 0;
rep->llinkto = NULL;
if (argfl || statreq) {
if ((*statf)(file, &statb) < 0) {
if (statf == lstat || lstat(file, &statb) < 0) {
fflush(stdout);
fprintf(stderr, "ls: ");
perror(file);
nfiles--;
return(NULL);
}
}
else {
rep->lnum = statb.st_ino;
rep->lsize = statb.st_size;
rep->lblks = statb.st_blocks;
switch(statb.st_mode&S_IFMT) {
case S_IFDIR:
rep->ltype = 'd';
break;
case S_IFBLK:
rep->ltype = 'b';
rep->lsize = statb.st_rdev;
break;
case S_IFCHR:
rep->ltype = 'c';
rep->lsize = statb.st_rdev;
break;
case S_IFIFO:
rep->ltype = 'p';
break;
case S_IFSOCK:
rep->ltype = 's';
rep->lsize = 0;
break;
case S_IFLNK:
rep->ltype = 'l';
if (lflg) {
cc = readlink(file, buf, MAXPATHLEN);
if (cc >= 0) {
/*
* here we follow the symbolic
* link to generate the proper
* Fflg marker for the object,
* eg, /bin -> /pub/bin/
*/
if (Fflg && !stat(file, &statb1))
switch (statb1.st_mode & S_IFMT){
case S_IFDIR:
buf[cc++] = '/';
break;
case S_IFSOCK:
buf[cc++] = '=';
break;
default:
if ( (statb1.st_mode & ~S_IFMT)
& 0111)
buf[cc++] = '*';
break;
}
buf[cc] = '\0';
rep->llinkto = malloc(strlen(buf) + 1);
if (rep->llinkto==NULL) {
fflush(stdout);
fprintf(stderr, "ls: out of memory\n");
err = 2;
nomocore = 1;
break;
}
strcpy(rep->llinkto, buf);
}
break;
}
/*
* this is a hack from UCB to avoid having
* ls /bin behave differently from ls /bin/
* when /bin is a symbolic link. We hack the
* hack to have that happen, but only for
* explicit arguments, by inspecting argfl.
*/
if (!argfl || stat(file, &statb1) < 0)
break;
if ((statb1.st_mode & S_IFMT) == S_IFDIR) {
statb = statb1;
rep->ltype = 'd';
rep->lsize = statb.st_size;
rep->lblks = statb.st_blocks;
}
break;
default:
rep->ltype = '-';
}
rep->lflags = statb.st_mode & ~S_IFMT;
/* mask ISARG and other file-type bits */
rep->luid = statb.st_uid;
rep->lgid = statb.st_gid;
rep->lnl = statb.st_nlink;
if(uflg)
rep->lmtime = statb.st_atime;
else if (cflg)
rep->lmtime = statb.st_ctime;
else
rep->lmtime = statb.st_mtime;
if (rep->ltype != 'b' && rep->ltype != 'c')
tblocks += statb.st_blocks;
}
}
return(rep);
}
/* returns pathname of the form dir/file;
* dir is a null-terminated string;
*/
char *
makename(dir, file)
char *dir, *file;
{
static char dfile[MAXPATHLEN+1]; /* dfile is static as this is returned
* by makename();
*/
if (strlen(dir)+1+strlen(file) > MAXPATHLEN) {
fprintf(stderr, "ls: filename too long\n");
exit(1);
}
if (strcmp(dir, "") == 0 || strcmp(dir, ".") == 0) {
(void) strcpy(dfile, file);
return(dfile);
}
(void) strcpy(dfile, dir);
if (dir[strlen(dir) - 1] != '/' && *file != '/')
(void) strcat(dfile, "/");
(void) strcat(dfile, file);
return(dfile);
}
/* rest should be done with nameserver or database */
#include <pwd.h>
#include <grp.h>
#include <utmp.h>
struct utmp utmp;
#define NMAX (sizeof (utmp.ut_name))
#define SCPYN(a, b) strncpy(a, b, NMAX)
#undef MAXUID
#define MAXUID 2048
#define MINUID -2 /* for nfs */
#define MAXGID 300
char namebuf[MAXUID - MINUID][NMAX+1];
char (*names)[NMAX+1] = namebuf - MINUID;
char outrangename[NMAX+1];
int outrangeuid = -1;
char groups[MAXGID][NMAX+1];
char outrangegroup[NMAX+1];
int outrangegid = -1;
char *
getname(uid)
{
register struct passwd *pw;
extern struct passwd *getpwuid();
if (uid >= MINUID && uid < MAXUID && names[uid][0])
return (&names[uid][0]);
if (uid >= MINUID && uid == outrangeuid)
return (outrangename);
if (uid < MINUID)
return (NULL);
pw = getpwuid(uid);
if (pw == NULL)
return (NULL);
if (uid >= MINUID && uid < MAXUID) {
SCPYN(names[uid], pw->pw_name);
return (&names[uid][0]);
}
outrangeuid = uid;
SCPYN(outrangename, pw->pw_name);
return (outrangename);
}
char *
getgroup(gid)
{
register struct group *gr;
static init;
extern struct group *getgrent();
if (gid >= 0 && gid < MAXGID && groups[gid][0])
return (&groups[gid][0]);
if (gid >= 0 && gid == outrangegid)
return (outrangegroup);
rescan:
if (init == 2) {
if (gid < MAXGID)
return (0);
setgrent();
while (gr = getgrent()) {
if (gr->gr_gid != gid)
continue;
outrangegid = gr->gr_gid;
SCPYN(outrangegroup, gr->gr_name);
endgrent();
return (outrangegroup);
}
endgrent();
return (0);
}
if (init == 0)
setgrent(), init = 1;
while (gr = getgrent()) {
if (gr->gr_gid < 0 || gr->gr_gid >= MAXGID) {
if (gr->gr_gid == gid) {
outrangegid = gr->gr_gid;
SCPYN(outrangegroup, gr->gr_name);
return (outrangegroup);
}
continue;
}
if (groups[gr->gr_gid][0])
continue;
SCPYN(groups[gr->gr_gid], gr->gr_name);
if (gr->gr_gid == gid)
return (&groups[gid][0]);
}
init = 2;
goto rescan;
}
compar(pp1, pp2) /* return >0 if item pointed by pp2 should appear first */
struct lbuf **pp1, **pp2;
{
register struct lbuf *p1, *p2;
p1 = *pp1;
p2 = *pp2;
if (dflg==0) {
/* compare two names in ls-command one of which is file
* and the other is a directory;
* this portion is not used for comparing files within
* a directory name of ls-command;
*/
if (p1->lflags&ISARG && p1->ltype=='d') {
if (!(p2->lflags&ISARG && p2->ltype=='d'))
return(1);
}
else {
if (p2->lflags&ISARG && p2->ltype=='d')
return(-1);
}
}
if (tflg) {
if(p2->lmtime == p1->lmtime)
return(0);
else if(p2->lmtime > p1->lmtime)
return(rflg);
else return(-rflg);
}
else
return(rflg * strcmp(p1->lname, p2->lname));
}
pprintf(s)
register char *s;
{
register int c;
register int cc;
while(c = *s++) {
if (!isprint(c)) {
if (qflg)
c = '?';
else if (bflg) {
curcol += 3;
putc ('\\', stdout);
cc = '0' + (c>>6 & 07);
putc (cc, stdout);
cc = '0' + (c>>3 & 07);
putc (cc, stdout);
c = '0' + (c & 07);
}
}
curcol++;
putc(c, stdout);
}
}

24
5bin/m4/Makefile Normal file
View File

@@ -0,0 +1,24 @@
#
# @(#)Makefile 1.1 92/07/30 SMI; from S5R2 1.3
#
YACCRM=-rm
CFLAGS = -O
m4: m4.o m4ext.o m4macs.o m4y.o
$(CC) $(LDFLAGS) -o m4 m4.o m4ext.o m4macs.o m4y.o
m4.o: m4.c m4.h
m4ext.o: m4ext.c
m4macs.o: m4macs.c
m4y.o: m4y.y
test:
rtest m4
install: m4
install -s m4 $(DESTDIR)/usr/5bin
clean:
-rm -f *.o
$(YACCRM) -f y.tab.c
-rm -f m4

851
5bin/m4/m4.c Normal file
View File

@@ -0,0 +1,851 @@
#ifndef lint
static char sccsid[] = "@(#)m4.c 1.1 92/07/30 SMI"; /* from S5R2 1.3 */
#endif
#include <stdio.h>
#include <signal.h>
#include "m4.h"
#define match(c,s) (c==*s && (!s[1] || inpmatch(s+1)))
main(argc,argv)
char **argv;
{
register t;
#ifdef gcos
tempfile = "m4*tempa";
#endif
#ifdef unix
{
static sigs[] = {SIGHUP, SIGINT, SIGPIPE, 0};
for (t=0; sigs[t]; ++t)
if (signal(sigs[t], SIG_IGN) != SIG_IGN)
signal(sigs[t],catchsig);
}
tempfile = mktemp("/tmp/m4aXXXXX");
close(creat(tempfile,0));
#endif
procnam = argv[0];
getflags(&argc,&argv);
initalloc();
setfname("-");
if (argc>1) {
--argc;
++argv;
if (strcmp(argv[0],"-")) {
ifile[ifx] = xfopen(argv[0],"r");
setfname(argv[0]);
}
}
for (;;) {
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
token[0] = t;
token[1] = EOS;
if (t==EOF) {
if (ifx > 0) {
fclose(ifile[ifx]);
ipflr = ipstk[--ifx];
continue;
}
getflags(&argc,&argv);
if (argc<=1)
if (Wrapstr) {
pbstr(Wrapstr);
Wrapstr = NULL;
continue;
} else
break;
--argc;
++argv;
if (ifile[ifx]!=stdin)
fclose(ifile[ifx]);
if (*argv[0]=='-')
ifile[ifx] = stdin;
else
ifile[ifx] = xfopen(argv[0],"r");
setfname(argv[0]);
continue;
}
if (isalpha(t) || t == '_') {
register char *tp = token+1;
register char tc;
register tlim = toksize;
struct nlist *macadd; /* temp variable */
for (;;) {
if (ip > ipflr)
tc = *--ip;
else {
if (feof(ifile[ifx]))
tc = EOF;
else {
tc = getc(ifile[ifx]);
if (tc == '\n')
fline[ifx]++;
}
}
if (!isalnum(tc) && tc != '_')
break;
*tp++ = tc;
if (--tlim<=0)
error2("more than %d chars in word",
toksize);
}
putbak(tc);
*tp = EOS;
macadd = lookup(token);
*Ap = (char *) macadd;
if (macadd->def) {
if ((char *) (++Ap) >= astklm) {
--Ap;
error2(astkof,stksize);
}
if (Cp++==NULL)
Cp = callst;
Cp->argp = Ap;
*Ap++ = op;
puttok(token);
stkchr(EOS);
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
putbak(t);
if (t!='(')
pbstr("()");
else /* try to fix arg count */
*Ap++ = op;
Cp->plev = 0;
} else {
puttok(token);
}
} else if (match(t,lquote)) {
register qlev = 1;
for (;;) {
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
token[0] = t;
token[1] = EOS;
if (match(t,rquote)) {
if (--qlev > 0)
puttok(token);
else
break;
} else if (match(t,lquote)) {
++qlev;
puttok(token);
} else {
if (t==EOF)
error("EOF in quote");
putchr(t);
}
}
} else if (match(t,lcom)) {
puttok(token);
for (;;) {
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
token[0] = t;
token[1] = EOS;
if (match(t,rcom)) {
puttok(token);
break;
} else {
if (t==EOF)
error("EOF in comment");
putchr(t);
}
}
} else if (Cp==NULL) {
putchr(t);
} else if (t=='(') {
if (Cp->plev)
stkchr(t);
else {
/* skip white before arg */
do {
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
} while (isspace(t));
putbak(t);
}
++Cp->plev;
} else if (t==')') {
--Cp->plev;
if (Cp->plev==0) {
stkchr(EOS);
expand(Cp->argp,Ap-Cp->argp-1);
op = *Cp->argp;
Ap = Cp->argp-1;
if (--Cp < callst)
Cp = NULL;
} else
stkchr(t);
} else if (t==',' && Cp->plev<=1) {
stkchr(EOS);
*Ap = op;
if ((char *) (++Ap) >= astklm) {
--Ap;
error2(astkof,stksize);
}
do {
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
} while (isspace(t));
putbak(t);
} else
stkchr(t);
}
if (Cp!=NULL)
error("EOF in argument list");
delexit(OK);
/* NOTREACHED */
}
char *inpmatch(s)
register char *s;
{
register char *tp = token+1;
register char t;
while (*s) {
if (ip > ipflr)
t = *--ip;
else {
if (feof(ifile[ifx]))
t = EOF;
else {
t = getc(ifile[ifx]);
if (t == '\n')
fline[ifx]++;
}
}
*tp++ = t;
if (t != *s++) {
*tp = EOS;
pbstr(token+1);
return 0;
}
}
*tp = EOS;
return token;
}
getflags(xargc,xargv)
register int *xargc;
register char ***xargv;
{
while (*xargc > 1) {
register char *arg = (*xargv)[1];
if (arg[0]!='-' || arg[1]==EOS)
break;
switch (arg[1]) {
case 'B':
bufsize = atoi(&arg[2]);
break;
case 'D':
{
register char *t;
char *s[2];
initalloc();
for (t = s[0] = &arg[2]; *t; t++)
if (*t=='=') {
*t++ = EOS;
break;
}
s[1] = t;
dodef(&s[-1],2);
break;
}
case 'H':
hshsize = atoi(&arg[2]);
break;
case 'S':
stksize = atoi(&arg[2]);
break;
case 'T':
toksize = atoi(&arg[2]);
break;
case 'U':
{
char *s[1];
initalloc();
s[0] = &arg[2];
doundef(&s[-1],1);
break;
}
case 'e':
#ifdef unix
setbuf(stdout,(char *) NULL);
signal(SIGINT,SIG_IGN);
#endif
break;
case 's':
/* turn on line sync */
sflag = 1;
break;
default:
fprintf(stderr,"%s: bad option: %s\n",
procnam,arg);
delexit(NOT_OK);
}
(*xargv)++;
--(*xargc);
}
return;
}
initalloc()
{
static done = 0;
register t;
if (done++)
return;
hshtab = (struct nlist **) xcalloc(hshsize,sizeof(struct nlist *));
callst = (struct call *) xcalloc(stksize/3+1,sizeof(struct call));
Ap = argstk = (char **) xcalloc(stksize+3,sizeof(char *));
ipstk[0] = ipflr = ip = ibuf = xcalloc(bufsize+1,sizeof(char));
op = obuf = xcalloc(bufsize+1,sizeof(char));
token = xcalloc(toksize+1,sizeof(char));
astklm = (char *) (&argstk[stksize]);
ibuflm = &ibuf[bufsize];
obuflm = &obuf[bufsize];
toklm = &token[toksize];
for (t=0; barray[t].bname; ++t) {
static char p[2] = {0, EOS};
p[0] = t|~LOW7;
install(barray[t].bname,p,NOPUSH);
}
#ifdef unix
install("unix",nullstr,NOPUSH);
#endif
#ifdef gcos
install("gcos",nullstr,NOPUSH);
#endif
}
struct nlist *
install(nam,val,mode)
char *nam;
register char *val;
{
register struct nlist *np;
register char *cp;
int l;
if (mode==PUSH)
lookup(nam); /* lookup sets hshval */
else
while (undef(nam)) /* undef calls lookup */
;
np = (struct nlist *) xcalloc(1,sizeof(*np));
np->name = copy(nam);
np->next = hshtab[hshval];
hshtab[hshval] = np;
cp = xcalloc((l=strlen(val))+1,sizeof(*val));
np->def = cp;
cp = &cp[l];
while (*val)
*--cp = *val++;
}
struct nlist *
lookup(str)
char *str;
{
register char *s1;
register struct nlist *np;
static struct nlist nodef;
s1 = str;
for (hshval = 0; *s1; )
hshval += *s1++;
hshval %= hshsize;
for (np = hshtab[hshval]; np!=NULL; np = np->next) {
if (!strcmp(str, np->name))
return(np);
}
return(&nodef);
}
expand(a1,c)
char **a1;
{
register char *dp;
register struct nlist *sp;
sp = (struct nlist *) a1[-1];
if (sp->tflag || trace) {
int i;
fprintf(stderr,"Trace(%d): %s",Cp-callst,a1[0]);
if (c > 0) {
fprintf(stderr,"(%s",chkbltin(a1[1]));
for (i=2; i<=c; ++i)
fprintf(stderr,",%s",chkbltin(a1[i]));
fprintf(stderr,")");
}
fprintf(stderr,"\n");
}
dp = sp->def;
for (; *dp; ++dp) {
if (*dp&~LOW7) {
(*barray[*dp&LOW7].bfunc)(a1,c);
} else if (dp[1]=='$') {
if (isdigit(*dp)) {
register n;
if ((n = *dp-'0') <= c)
pbstr(a1[n]);
++dp;
} else if (*dp=='#') {
pbnum((long) c);
++dp;
} else if (*dp=='*' || *dp=='@') {
register i = c;
char **a = a1;
if (i > 0)
for (;;) {
if (*dp=='@')
pbstr(rquote);
pbstr(a[i--]);
if (*dp=='@')
pbstr(lquote);
if (i <= 0)
break;
pbstr(",");
}
++dp;
} else
putbak(*dp);
} else
putbak(*dp);
}
}
setfname(s)
register char *s;
{
strcpy(fname[ifx],s);
fname[ifx+1] = fname[ifx]+strlen(s)+1;
fline[ifx] = 1;
nflag = 1;
lnsync(stdout);
}
lnsync(iop)
register FILE *iop;
{
static int cline = 0;
static int cfile = 0;
if (!sflag || iop!=stdout)
return;
if (nflag || ifx!=cfile) {
nflag = 0;
cfile = ifx;
fprintf(iop,"#line %d \"",cline = fline[ifx]);
fpath(iop);
fprintf(iop,"\"\n");
} else if (++cline != fline[ifx])
fprintf(iop,"#line %d\n",cline = fline[ifx]);
}
fpath(iop)
register FILE *iop;
{
register i;
fprintf(iop,"%s",fname[0]);
for (i=1; i<=ifx; ++i)
fprintf(iop,":%s",fname[i]);
}
catchsig()
{
#ifdef unix
signal(SIGHUP,SIG_IGN);
signal(SIGINT,SIG_IGN);
#endif
delexit(NOT_OK);
}
delexit(code)
{
register i;
cf = stdout;
/* if (ofx != 0) { /* quitting in middle of diversion */
/* ofx = 0;
/* code = NOT_OK;
/* }
*/
ofx = 0; /* ensure that everything comes out */
for (i=1; i<10; i++)
undiv(i,code);
tempfile[7] = 'a';
unlink(tempfile);
if (code==OK)
exit(code);
_exit(code);
}
puttok(tp)
register char *tp;
{
if (Cp) {
while (*tp)
stkchr(*tp++);
} else if (cf)
while (*tp)
sputchr(*tp++,cf);
}
pbstr(str)
register char *str;
{
register char *p;
for (p = str + strlen(str); --p >= str; )
putbak(*p);
}
undiv(i,code)
register i;
{
register FILE *fp;
register c;
if (i<1 || i>9 || i==ofx || !ofile[i])
return;
fclose(ofile[i]);
tempfile[7] = 'a'+i;
if (code==OK && cf) {
fp = xfopen(tempfile,"r");
while ((c=getc(fp)) != EOF)
sputchr(c,cf);
fclose(fp);
}
unlink(tempfile);
ofile[i] = NULL;
}
char *copy(s)
register char *s;
{
register char *p;
p = xcalloc(strlen(s)+1,sizeof(char));
strcpy(p, s);
return(p);
}
pbnum(num)
long num;
{
pbnbr(num,10,1);
}
pbnbr(nbr,base,len)
long nbr;
register base, len;
{
register neg = 0;
if (base<=0)
return;
if (nbr<0)
neg = 1;
else
nbr = -nbr;
while (nbr<0) {
register int i;
if (base>1) {
i = nbr%base;
nbr /= base;
# if (-3 % 2) != -1
while (i > 0) {
i -= base;
++nbr;
}
# endif
i = -i;
} else {
i = 1;
++nbr;
}
putbak(itochr(i));
--len;
}
while (--len >= 0)
putbak('0');
if (neg)
putbak('-');
}
itochr(i)
register i;
{
if (i>9)
return i-10+'A';
else
return i+'0';
}
long ctol(str)
register char *str;
{
register sign;
long num;
while (isspace(*str))
++str;
num = 0;
if (*str=='-') {
sign = -1;
++str;
}
else
sign = 1;
while (isdigit(*str))
num = num*10 + *str++ - '0';
return(sign * num);
}
min(a,b)
{
if (a>b)
return(b);
return(a);
}
FILE *
xfopen(name,mode)
char *name,
*mode;
{
FILE *fp;
if ((fp=fopen(name,mode))==NULL)
error(badfile);
return fp;
}
char *xcalloc(nbr,size)
{
register char *ptr;
if ((ptr=calloc((unsigned) nbr,(unsigned) size)) == NULL)
error(nocore);
return ptr;
}
error2(str,num)
char *str;
int num;
{
char buf[500];
sprintf(buf,str,num);
error(buf);
}
error(str)
char *str;
{
fprintf(stderr,"\n%s:",procnam);
fpath(stderr);
fprintf(stderr,":%d %s\n",fline[ifx],str);
if (Cp) {
register struct call *mptr;
/* fix limit */
*op = EOS;
(Cp+1)->argp = Ap+1;
for (mptr=callst; mptr<=Cp; ++mptr) {
register char **aptr, **lim;
aptr = mptr->argp;
lim = (mptr+1)->argp-1;
if (mptr==callst)
fputs(*aptr,stderr);
++aptr;
fputs("(",stderr);
if (aptr < lim)
for (;;) {
fputs(*aptr++,stderr);
if (aptr >= lim)
break;
fputs(",",stderr);
}
}
while (--mptr >= callst)
fputs(")",stderr);
fputs("\n",stderr);
}
delexit(NOT_OK);
}
char *chkbltin(s)
char *s;
{
static char buf[24];
if (*s&~LOW7){
sprintf(buf,"<%s>",barray[*s&LOW7].bname);
return buf;
}
return s;
}
int getchr()
{
if (ip > ipflr)
return (*--ip);
C = feof(ifile[ifx]) ? EOF : getc(ifile[ifx]);
if (C =='\n')
fline[ifx]++;
return (C);
}

96
5bin/m4/m4.h Normal file
View File

@@ -0,0 +1,96 @@
/* @(#)m4.h 1.1 92/07/30 SMI; from S5R2 1.3 */
#include <ctype.h>
#define EOS '\0'
#define LOW7 0177
#define MAXSYM 5
#define PUSH 1
#define NOPUSH 0
#define OK 0
#define NOT_OK 1
#define putbak(c) (ip < ibuflm? (*ip++ = (c)): error2(pbmsg,bufsize))
#define stkchr(c) (op < obuflm? (*op++ = (c)): error2(aofmsg,bufsize))
#define sputchr(c,f) (putc(c,f)=='\n'? lnsync(f): 0)
#define putchr(c) (Cp?stkchr(c):cf?(sflag?sputchr(c,cf):putc(c,cf)):0)
struct bs {
int (*bfunc)();
char *bname;
};
struct call {
char **argp;
int plev;
};
struct nlist {
char *name;
char *def;
char tflag;
struct nlist *next;
};
extern FILE *cf;
extern FILE *ifile[];
extern FILE *ofile[];
extern FILE *xfopen();
extern char **Ap;
extern char **argstk;
extern char *Wrapstr;
extern char *astklm;
extern char *inpmatch();
extern char *chkbltin();
extern char *calloc();
extern char *xcalloc();
extern char *copy();
extern char *mktemp();
extern char *strcpy();
extern char *fname[];
extern char *ibuf;
extern char *ibuflm;
extern char *ip;
extern char *ipflr;
extern char *ipstk[10];
extern char *obuf;
extern char *obuflm;
extern char *op;
extern char *procnam;
extern char *tempfile;
extern char *token;
extern char *toklm;
extern int C;
extern int getchr();
extern char aofmsg[];
extern char astkof[];
extern char badfile[];
extern char fnbuf[];
extern char lcom[];
extern char lquote[];
extern char nocore[];
extern char nullstr[];
extern char pbmsg[];
extern char rcom[];
extern char rquote[];
extern char type[];
extern int bufsize;
extern int catchsig();
extern int fline[];
extern int hshsize;
extern int hshval;
extern int ifx;
extern int nflag;
extern int ofx;
extern int sflag;
extern int stksize;
extern int sysrval;
extern int toksize;
extern int trace;
extern long ctol();
extern struct bs barray[];
extern struct call *Cp;
extern struct call *callst;
extern struct nlist **hshtab;
extern struct nlist *install();
extern struct nlist *lookup();

94
5bin/m4/m4ext.c Normal file
View File

@@ -0,0 +1,94 @@
#ifndef lint
static char sccsid[] = "@(#)m4ext.c 1.1 92/07/30 SMI"; /* from S5R2 1.3 */
#endif
#include "stdio.h"
#include "m4.h"
/* storage params */
int hshsize = 199; /* hash table size (prime) */
int bufsize = 4096; /* pushback & arg text buffers */
int stksize = 100; /* call stack */
int toksize = 512; /* biggest word ([a-z_][a-z0-9_]*) */
/* pushback buffer */
char *ibuf; /* buffer */
char *ibuflm; /* highest buffer addr */
char *ip; /* current position */
char *ipflr; /* buffer floor */
char *ipstk[10]; /* stack for "ipflr"s */
/* arg collection buffer */
char *obuf; /* buffer */
char *obuflm; /* high address */
char *op; /* current position */
/* call stack */
struct call *callst; /* stack */
struct call *Cp = NULL; /* position */
/* token storage */
char *token; /* buffer */
char *toklm; /* high addr */
/* file name and current line storage for line sync and diagnostics */
char fnbuf[200]; /* holds file name strings */
char *fname[11] = {fnbuf}; /* file name ptr stack */
int fline[10]; /* current line nbr stack */
/* input file stuff for "include"s */
FILE *ifile[10] = {stdin}; /* stack */
int ifx; /* stack index */
/* stuff for output diversions */
FILE *cf = stdout; /* current output file */
FILE *ofile[11] = {stdout}; /* output file stack */
int ofx; /* stack index */
/* comment markers */
char lcom[MAXSYM+1] = "#";
char rcom[MAXSYM+1] = "\n";
/* quote markers */
char lquote[MAXSYM+1] = "`";
char rquote[MAXSYM+1] = "'";
/* argument ptr stack */
char **argstk;
char *astklm; /* high address */
char **Ap; /* current position */
/* symbol table */
struct nlist **hshtab; /* hash table */
int hshval; /* last hash val */
/* misc */
char *procnam; /* argv[0] */
char *tempfile; /* used for diversion files */
char *Wrapstr; /* last pushback string for "m4wrap" */
int C; /* see "m4.h" macros */
char nullstr[] = "";
int nflag = 1; /* name flag, used for line sync code */
int sflag; /* line sync flag */
int sysrval; /* return val from syscmd */
int trace; /* global trace flag */
char aofmsg[] = "more than %d chars of argument text";
char astkof[] = "more than %d items on argument stack";
char badfile[] = "can't open file";
char nocore[] = "out of storage";
char pbmsg[] = "pushed back more than %d chars";

535
5bin/m4/m4macs.c Normal file
View File

@@ -0,0 +1,535 @@
#ifndef lint
static char sccsid[] = "@(#)m4macs.c 1.1 92/07/30 SMI"; /* from S5R2 1.3 */
#endif
#include <stdio.h>
#include <sys/param.h>
#include <signal.h>
#include <sys/types.h>
#if u3b
#include <sys/macro.h>
#else
#include <sys/sysmacros.h>
#endif
#include <sys/stat.h>
#include "m4.h"
#define arg(n) (c<(n)? nullstr: ap[n])
dochcom(ap,c)
char **ap;
{
register char *l = arg(1);
register char *r = arg(2);
if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
error("comment marker longer than %d chars",MAXSYM);
strcpy(lcom,l);
strcpy(rcom,*r?r:"\n");
}
docq(ap,c)
register char **ap;
{
register char *l = arg(1);
register char *r = arg(2);
if (strlen(l)>MAXSYM || strlen(r)>MAXSYM)
error("quote marker longer than %d chars", MAXSYM);
if (c<=1 && !*l) {
l = "`";
r = "'";
} else if (c==1) {
r = l;
}
strcpy(lquote,l);
strcpy(rquote,r);
}
dodecr(ap,c)
char **ap;
{
pbnum(ctol(arg(1))-1);
}
dodef(ap,c)
char **ap;
{
def(ap,c,NOPUSH);
}
def(ap,c,mode)
register char **ap;
{
register char *s;
register char sc;
if (c<1)
return;
s = ap[1];
sc = *s;
if (isalpha(sc) || sc == '_') {
do
sc = *++s;
while (isalnum(sc) || sc == '_');
}
if (sc || s==ap[1])
error("bad macro name");
if (strcmp(ap[1],ap[2])==0)
error("macro defined as itself");
install(ap[1],arg(2),mode);
}
dodefn(ap,c)
register char **ap;
register c;
{
register char *d;
while (c > 0)
if ((d = lookup(ap[c--])->def) != NULL) {
putbak(*rquote);
while (*d)
putbak(*d++);
putbak(*lquote);
}
}
dodiv(ap,c)
register char **ap;
{
register int f;
f = atoi(arg(1));
if (f>=10 || f<0) {
cf = NULL;
ofx = f;
return;
}
tempfile[7] = 'a'+f;
if (ofile[f] || (ofile[f]=xfopen(tempfile,"w"))) {
ofx = f;
cf = ofile[f];
}
}
/* ARGSUSED */
dodivnum(ap,c)
{
pbnum((long) ofx);
}
/* ARGSUSED */
dodnl(ap,c)
char *ap;
{
register t;
while ((t=getchr())!='\n' && t!=EOF)
;
}
dodump(ap,c)
char **ap;
{
register struct nlist *np;
register i;
if (c > 0)
while (c--) {
if ((np = lookup(*++ap))->name != NULL)
dump(np->name,np->def);
}
else
for (i=0; i<hshsize; i++)
for (np=hshtab[i]; np!=NULL; np=np->next)
dump(np->name,np->def);
}
dump(name,defnn)
register char *name,
*defnn;
{
register char *s = defnn;
fprintf(stderr,"%s:\t",name);
while (*s++)
;
--s;
while (s>defnn)
if (*--s&~LOW7)
fprintf(stderr,"<%s>",barray[*s&LOW7].bname);
else
fputc(*s,stderr);
fputc('\n',stderr);
}
doerrp(ap,c)
char **ap;
{
if (c > 0)
fprintf(stderr,"%s",ap[1]);
}
long evalval; /* return value from yacc stuff */
char *pe; /* used by grammar */
doeval(ap,c)
char **ap;
{
register base = atoi(arg(2));
register pad = atoi(arg(3));
evalval = 0;
if (c > 0) {
pe = ap[1];
if (yyparse()!=0)
error("invalid expression");
}
pbnbr(evalval, base>0?base:10, pad>0?pad:1);
}
doexit(ap,c)
char **ap;
{
delexit(atoi(arg(1)));
}
doif(ap,c)
register char **ap;
{
if (c < 3)
return;
while (c >= 3) {
if (strcmp(ap[1],ap[2])==0) {
pbstr(ap[3]);
return;
}
c -= 3;
ap += 3;
}
if (c > 0)
pbstr(ap[1]);
}
doifdef(ap,c)
char **ap;
{
if (c < 2)
return;
while (c >= 2) {
if (lookup(ap[1])->name != NULL) {
pbstr(ap[2]);
return;
}
c -= 2;
ap += 2;
}
if (c > 0)
pbstr(ap[1]);
}
doincl(ap,c)
char **ap;
{
incl(ap,c,1);
}
incl(ap,c,noisy)
register char **ap;
{
if (c>0 && strlen(ap[1])>0) {
if (ifx >= 9)
error("input file nesting too deep (9)");
if ((ifile[++ifx]=fopen(ap[1],"r"))==NULL){
--ifx;
if (noisy)
error(badfile);
} else {
ipstk[ifx] = ipflr = ip;
setfname(ap[1]);
}
}
}
doincr(ap,c)
char **ap;
{
pbnum(ctol(arg(1))+1);
}
doindex(ap,c)
char **ap;
{
register char *subj = arg(1);
register char *obj = arg(2);
register i;
for (i=0; *subj; ++i)
if (leftmatch(subj++,obj)) {
pbnum( (long) i );
return;
}
pbnum( (long) -1 );
}
leftmatch(str,substr)
register char *str;
register char *substr;
{
while (*substr)
if (*str++ != *substr++)
return (0);
return (1);
}
dolen(ap,c)
char **ap;
{
pbnum((long) strlen(arg(1)));
}
domake(ap,c)
char **ap;
{
if (c > 0)
pbstr(mktemp(ap[1]));
}
dopopdef(ap,c)
char **ap;
{
register i;
for (i=1; i<=c; ++i)
undef(ap[i]);
}
dopushdef(ap,c)
char **ap;
{
def(ap,c,PUSH);
}
doshift(ap,c)
register char **ap;
register c;
{
if (c <= 1)
return;
for (;;) {
pbstr(rquote);
pbstr(ap[c--]);
pbstr(lquote);
if (c <= 1)
break;
pbstr(",");
}
}
dosincl(ap,c)
char **ap;
{
incl(ap,c,0);
}
dosubstr(ap,c)
register char **ap;
{
char *str;
int inlen, outlen;
register offset, ix;
inlen = strlen(str=arg(1));
offset = atoi(arg(2));
if (offset<0 || offset>=inlen)
return;
outlen = c>=3? atoi(ap[3]): inlen;
ix = min(offset+outlen,inlen);
while (ix > offset)
putbak(str[--ix]);
}
dosyscmd(ap,c)
char **ap;
{
sysrval = 0;
if (c > 0) {
fflush(stdout);
sysrval = system(ap[1]);
}
}
/* ARGSUSED */
dosysval(ap,c)
char **ap;
{
pbnum((long) (sysrval < 0 ? sysrval :
(sysrval >> 8) & ((1 << 8) - 1)) |
((sysrval & ((1 << 8) - 1)) << 8));
}
dotransl(ap,c)
char **ap;
{
char *sink, *fr, *sto;
register char *source, *to;
if (c<1)
return;
sink = ap[1];
fr = arg(2);
sto = arg(3);
for (source = ap[1]; *source; source++) {
register char *i;
to = sto;
for (i = fr; *i; ++i) {
if (*source==*i)
break;
if (*to)
++to;
}
if (*i) {
if (*to)
*sink++ = *to;
} else
*sink++ = *source;
}
*sink = EOS;
pbstr(ap[1]);
}
dotroff(ap,c)
register char **ap;
{
register struct nlist *np;
trace = 0;
while (c > 0)
if ((np=lookup(ap[c--]))->name)
np->tflag = 0;
}
dotron(ap,c)
register char **ap;
{
register struct nlist *np;
trace = !*arg(1);
while (c > 0)
if ((np=lookup(ap[c--]))->name)
np->tflag = 1;
}
doundef(ap,c)
char **ap;
{
register i;
for (i=1; i<=c; ++i)
while (undef(ap[i]))
;
}
undef(nam)
char *nam;
{
register struct nlist *np, *tnp;
if ((np=lookup(nam))->name==NULL)
return 0;
tnp = hshtab[hshval]; /* lookup sets hshval */
if (tnp==np) /* it's in first place */
hshtab[hshval] = tnp->next;
else {
while (tnp->next != np)
tnp = tnp->next;
tnp->next = np->next;
}
cfree(np->name);
cfree(np->def);
cfree((char *) np);
return 1;
}
doundiv(ap,c)
register char **ap;
{
register int i;
if (c<=0)
for (i=1; i<10; i++)
undiv(i,OK);
else
while (--c >= 0)
undiv(atoi(*++ap),OK);
}
dowrap(ap,c)
char **ap;
{
register char *a = arg(1);
if (Wrapstr)
cfree(Wrapstr);
Wrapstr = xcalloc(strlen(a)+1,sizeof(char));
strcpy(Wrapstr,a);
}
struct bs barray[] = {
dochcom, "changecom",
docq, "changequote",
dodecr, "decr",
dodef, "define",
dodefn, "defn",
dodiv, "divert",
dodivnum, "divnum",
dodnl, "dnl",
dodump, "dumpdef",
doerrp, "errprint",
doeval, "eval",
doexit, "m4exit",
doif, "ifelse",
doifdef, "ifdef",
doincl, "include",
doincr, "incr",
doindex, "index",
dolen, "len",
domake, "maketemp",
dopopdef, "popdef",
dopushdef, "pushdef",
doshift, "shift",
dosincl, "sinclude",
dosubstr, "substr",
dosyscmd, "syscmd",
dosysval, "sysval",
dotransl, "translit",
dotroff, "traceoff",
dotron, "traceon",
doundef, "undefine",
doundiv, "undivert",
dowrap, "m4wrap",
0, 0
};

131
5bin/m4/m4y.y Normal file
View File

@@ -0,0 +1,131 @@
%{
#ifndef lint
static char sccsid[] = "@(#)m4y.y 1.1 92/07/30 SMI"; /* from S5R2 1.2 */
#endif
extern long evalval;
#define YYSTYPE long
%}
%term DIGITS
%left OROR
%left ANDAND
%left '|' '^'
%left '&'
%right '!' '~'
%nonassoc GT GE LT LE NE EQ
%left '+' '-'
%left '*' '/' '%'
%right POWER
%right UMINUS
%%
s : e ={ evalval = $1; }
| ={ evalval = 0; }
;
e : e OROR e ={ $$ = ($1!=0 || $3!=0) ? 1 : 0; }
| e ANDAND e ={ $$ = ($1!=0 && $3!=0) ? 1 : 0; }
| '!' e ={ $$ = $2 == 0; }
| '~' e ={ $$ = ~$2; }
| e EQ e ={ $$ = $1 == $3; }
| e NE e ={ $$ = $1 != $3; }
| e GT e ={ $$ = $1 > $3; }
| e GE e ={ $$ = $1 >= $3; }
| e LT e ={ $$ = $1 < $3; }
| e LE e ={ $$ = $1 <= $3; }
| e '|' e ={ $$ = ($1|$3); }
| e '&' e ={ $$ = ($1&$3); }
| e '^' e ={ $$ = ($1^$3); }
| e '+' e ={ $$ = ($1+$3); }
| e '-' e ={ $$ = ($1-$3); }
| e '*' e ={ $$ = ($1*$3); }
| e '/' e ={ $$ = ($1/$3); }
| e '%' e ={ $$ = ($1%$3); }
| '(' e ')' ={ $$ = ($2); }
| e POWER e ={ for ($$=1; $3-->0; $$ *= $1); }
| '-' e %prec UMINUS ={ $$ = $2-1; $$ = -$2; }
| '+' e %prec UMINUS ={ $$ = $2-1; $$ = $2; }
| DIGITS ={ $$ = evalval; }
;
%%
extern char *pe;
yylex() {
while (*pe==' ' || *pe=='\t' || *pe=='\n')
pe++;
switch(*pe) {
case '\0':
case '+':
case '-':
case '/':
case '%':
case '^':
case '~':
case '(':
case ')':
return(*pe++);
case '*':
return(peek('*', POWER, '*'));
case '>':
return(peek('=', GE, GT));
case '<':
return(peek('=', LE, LT));
case '=':
return(peek('=', EQ, EQ));
case '|':
return(peek('|', OROR, '|'));
case '&':
return(peek('&', ANDAND, '&'));
case '!':
return(peek('=', NE, '!'));
default: {
register base;
evalval = 0;
if (*pe == '0') {
if (*++pe=='x' || *pe=='X') {
base = 16;
++pe;
} else
base = 8;
} else
base = 10;
for (;;) {
register c, dig;
c = *pe;
if (c>='0' && c<='9')
dig = c - '0';
else if (c>='a' && c<='f')
dig = c - 'a' + 10;
else if (c>='A' && c<='F')
dig = c - 'A' + 10;
else
break;
evalval = evalval*base + dig;
++pe;
}
return(DIGITS);
}
}
}
peek(c, r1, r2)
{
if (*++pe != c)
return(r2);
++pe;
return(r1);
}
/* VARARGS */
yyerror() {;}

58
5bin/nohup.c Normal file
View File

@@ -0,0 +1,58 @@
#ifndef lint
static char sccsid[] = "@(#)nohup.c 1.1 92/07/30 SMI"; /* from S5R2 1.4 */
#endif
#include <stdio.h>
#include <signal.h>
char nout[100] = "nohup.out";
char *getenv();
extern char *sys_errlist[];
extern int errno;
main(argc, argv)
char **argv;
{
char *home;
FILE *temp;
int err;
if(argc < 2) {
fprintf(stderr,"usage: nohup command arg ...\n");
exit(1);
}
argv[argc] = 0;
signal(SIGHUP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
if(isatty(1)) {
if( (temp = fopen(nout, "a")) == NULL) {
if((home=getenv("HOME")) == NULL) {
fprintf(stderr,"nohup: cannot open/create nohup.out\n");
exit(1);
}
strcpy(nout,home);
strcat(nout,"/nohup.out");
if(freopen(nout, "a", stdout) == NULL) {
fprintf(stderr,"nohup: cannot open/create nohup.out\n");
exit(1);
}
}
else {
fclose(temp);
freopen(nout, "a", stdout);
}
fprintf(stderr, "Sending output to %s\n", nout);
}
if(isatty(2)) {
close(2);
dup(1);
}
execvp(argv[1], &argv[1]);
err = errno;
/* It failed, so print an error */
freopen("/dev/tty", "w", stderr);
fprintf(stderr,"%s: %s: %s\n", argv[0], argv[1], sys_errlist[err]);
exit(1);
/* NOTREACHED */
}

1525
5bin/pg.c Normal file

File diff suppressed because it is too large Load Diff

605
5bin/pr.c Normal file
View File

@@ -0,0 +1,605 @@
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)pr.c 1.1 92/07/30 SMI"; /* from S5R3 1.7 */
#endif
/*
* PR command (print files in pages and columns, with headings)
* 2+head+2+page[56]+5
*/
#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <locale.h>
#include <sys/types.h>
#include <sys/stat.h>
#define ESC '\033'
#define LENGTH 66
#define LINEW 72
#define NUMW 5
#define MARGIN 10
#define DEFTAB 8
#define NFILES 10
#define STDINNAME() nulls
#define PROMPT() putc('\7', stderr) /* BEL */
#define NOFILE nulls
#define TABS(N,C) if ((N = intopt(argv, &C)) < 0) N = DEFTAB
#define ETABS (Inpos % Etabn)
#define ITABS (Itabn > 0 && Nspace >= (nc = Itabn - Outpos % Itabn))
#define NSEPC '\t'
#define HEAD "%12.12s %4.4s %s Page %d\n\n\n", date+4, date+20, head, Page
#define cerror(S) fprintf(stderr, "pr: %s", S)
#define done() if (Ttyout) chmod(Ttyout, Mode)
typedef char CHAR;
typedef int ANY;
typedef unsigned UNS;
typedef struct { FILE *f_f; char *f_name; int f_nextc; } FILS;
ANY *getspace();
FILS *Files;
FILE *fopen(), *mustopen();
int Mode;
int Multi = 0, Nfiles = 0, Error = 0, onintr();
char nulls[] = "";
char *ttyname(), *Ttyout, obuf[BUFSIZ];
extern void exit();
extern void _exit();
extern char *malloc();
extern time_t time();
void
fixtty()
{
struct stat sbuf;
setbuf(stdout, obuf);
if (signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, onintr);
if (Ttyout= ttyname(fileno(stdout))) { /* is stdout a tty? */
stat(Ttyout, &sbuf);
Mode = sbuf.st_mode&0777; /* save permissions */
chmod(Ttyout, 0600);
}
return;
}
char *GETDATE() /* return date file was last modified */
{
char *ctime();
static char *now = NULL;
static struct stat sbuf, nbuf;
if (Nfiles > 1 || Files->f_name == nulls) {
if (now == NULL)
{ time(&nbuf.st_mtime); now = ctime(&nbuf.st_mtime); }
return (now);
} else {
stat(Files->f_name, &sbuf);
return (ctime(&sbuf.st_mtime));
}
}
char *ffiler(s) char *s;
{
static char buf[100];
sprintf(buf, "can't open %s", s);
return (buf);
}
main(argc, argv) char *argv[];
{
FILS fstr[NFILES];
int nfdone = 0;
setlocale(LC_ALL, "");
Files = fstr;
for (argc = findopt(argc, argv); argc > 0; --argc, ++argv)
if (Multi == 'm') {
if (Nfiles >= NFILES - 1) die("too many files");
if (mustopen(*argv, &Files[Nfiles++]) == NULL)
++nfdone; /* suppress printing */
} else {
if (print(*argv))
fclose(Files->f_f);
++nfdone;
}
if (!nfdone) /* no files named, use stdin */
print(NOFILE); /* on GCOS, use current file, if any */
errprint(); /* print accumulated error reports */
exit(Error); /*NOTREACHED*/
}
long Lnumb = 0;
FILE *Ttyin = stdin;
int Dblspace = 1, Fpage = 1, Formfeed = 0,
Length = LENGTH, Linew = 0, Offset = 0, Ncols = 1, Pause = 0, Sepc = 0,
Colw, Plength, Margin = MARGIN, Numw, Nsepc = NSEPC, Report = 1,
Etabn = 0, Etabc = '\t', Itabn = 0, Itabc = '\t';
char *Head = NULL;
CHAR *Buffer = NULL, *Bufend;
typedef struct { CHAR *c_ptr, *c_ptr0; long c_lno; } *COLP;
COLP Colpts;
/* findopt() returns eargc modified to be */
/* the number of explicitly supplied */
/* filenames, including '-', the explicit */
/* request to use stdin. eargc == 0 implies */
/* that no filenames were supplied and */
/* stdin should be used. */
findopt(argc, argv) char *argv[];
{
char **eargv = argv;
int eargc = 0, c;
int mflg = 0, aflg = 0;
void usage();
fixtty();
while (--argc > 0) {
switch (c = **++argv) {
case '-':
if ((c = *++*argv) == '\0') break;
case '+':
do {
if (isdigit(c)) {
--*argv;
Ncols = atoix(argv);
}
else
switch (c) {
case '+': if ((Fpage = atoix(argv)) < 1)
Fpage = 1;
continue;
case 'd': Dblspace = 2;
continue;
case 'e': TABS(Etabn, Etabc);
continue;
case 'f': ++Formfeed;
continue;
case 'h': if (--argc > 0)
Head = argv[1];
continue;
case 'i': TABS(Itabn, Itabc);
continue;
case 'l': Length = atoix(argv);
continue;
case 'a': aflg++;
Multi = c;
continue;
case 'm': mflg++;
Multi = c;
continue;
case 'o': Offset = atoix(argv);
continue;
case 'p': ++Pause;
continue;
case 'r': Report = 0;
continue;
case 's': if ((Sepc = (*argv)[1]) != '\0')
++*argv;
else
Sepc = '\t';
continue;
case 't': Margin = 0;
continue;
case 'w': Linew = atoix(argv);
continue;
case 'n': ++Lnumb;
if ((Numw = intopt(argv,&Nsepc)) <= 0)
Numw = NUMW;
continue;
default :
fprintf(stderr,
"pr: unknown option, %c\n",
(char)c);
usage();
}
/* Advance over options */
/* until null is found. */
/* Allows clumping options */
/* as in "pr -pm f1 f2". */
} while ((c = *++*argv) != '\0');
if (Head == argv[1]) ++argv;
continue;
}
*eargv++ = *argv;
++eargc; /* count the filenames */
}
if (mflg && (Ncols > 1)) {
fprintf(stderr, "pr: only one of either -m or -column allowed\n");
usage();
}
if (aflg && (Ncols < 2)) {
fprintf(stderr, "pr: -a valid only with -column\n");
usage();
}
if (Length == 0) Length = LENGTH;
if (Length <= Margin) Margin = 0;
Plength = Length - Margin/2;
if (Multi == 'm') Ncols = eargc;
switch (Ncols) {
case 0:
Ncols = 1;
case 1:
break;
default:
if (Etabn == 0) /* respect explicit tab specification */
Etabn = DEFTAB;
if (Itabn == 0)
Itabn = DEFTAB;
}
if (Linew == 0) Linew = Ncols != 1 && Sepc == 0 ? LINEW : 512;
if (Lnumb) {
int numw;
if (Nsepc == '\t') {
if(Itabn == 0)
numw = Numw + DEFTAB - (Numw % DEFTAB);
else
numw = Numw + Itabn - (Numw % Itabn);
}else {
numw = Numw + ((isprint(Nsepc)) ? 1 : 0);
}
Linew -= (Multi == 'm') ? numw : numw * Ncols;
}
if ((Colw = (Linew - Ncols + 1)/Ncols) < 1)
die("width too small");
if (Ncols != 1 && Multi == 0) {
UNS buflen = ((UNS)(Plength/Dblspace + 1))*(Linew+1)*sizeof(CHAR);
Buffer = (CHAR *)getspace(buflen);
Bufend = &Buffer[buflen];
Colpts = (COLP)getspace((UNS)((Ncols+1)*sizeof(*Colpts)));
}
/* is stdin not a tty? */
if (Ttyout && (Pause || Formfeed) && !ttyname(fileno(stdin)))
Ttyin = fopen("/dev/tty", "r");
return (eargc);
}
intopt(argv, optp) char *argv[]; int *optp;
{
int c;
if ((c = (*argv)[1]) != '\0' && !isdigit(c)) { *optp = c; ++*argv; }
return ((c = atoix(argv)) != 0 ? c : -1);
}
int Page, C = '\0', Nspace, Inpos;
print(name) char *name;
{
static int notfirst = 0;
char *date = NULL, *head = NULL;
int c;
if (Multi != 'm' && mustopen(name, &Files[0]) == NULL) return (0);
if (Multi == 'm' && Nfiles == 0 && mustopen(name, &Files[0]) == NULL)
die("cannot open stdin");
if (Buffer) ungetc(Files->f_nextc, Files->f_f);
if (Lnumb) Lnumb = 1;
for (Page = 0; ; putpage()) {
if (C == EOF) break;
if (Buffer) nexbuf();
Inpos = 0;
if (get(0) == EOF) break;
Inpos = 0;
fflush(stdout);
if (++Page >= Fpage) {
if (Ttyout && (Pause || Formfeed && !notfirst++)) {
if (Ttyin != NULL) {
PROMPT(); /* prompt with bell and pause */
while ((c = getc(Ttyin)) != EOF && c != '\n') ;
}
}
if (Margin == 0) continue;
if (date == NULL) date = GETDATE();
if (head == NULL) head = Head != NULL ? Head :
Nfiles < 2 ? Files->f_name : nulls;
printf("\n\n");
Nspace = Offset;
putspace();
printf(HEAD);
}
}
C = '\0';
return (1);
}
int Outpos, Lcolpos, Pcolpos, Line;
putpage()
{
register int colno;
for (Line = Margin/2; ; get(0)) {
for (Nspace = Offset, colno = 0, Outpos = 0; C != '\f'; ) {
if (Lnumb && C != EOF && ((colno == 0 && Multi == 'm') || Multi != 'm')) {
if (Page >= Fpage) {
putspace();
printf("%*ld%c", Numw, Buffer ?
Colpts[colno].c_lno++ : Lnumb, Nsepc);
}
++Lnumb;
}
for (Lcolpos = 0, Pcolpos = 0;
C != '\n' && C != '\f' && C != EOF; get(colno))
put(C);
if (C == EOF || ++colno == Ncols ||
C == '\n' && get(colno) == EOF) break;
if (Sepc) put(Sepc);
else if ((Nspace += Colw - Lcolpos + 1) < 1) Nspace = 1;
}
if (C == EOF) {
if (Margin != 0) break;
if (colno != 0) put('\n');
return;
}
if (C == '\f') break;
put('\n');
if (Dblspace == 2 && Line < Plength) put('\n');
if (Line >= Plength) break;
}
if (Formfeed) put('\f');
else while (Line < Length) put('\n');
}
nexbuf()
{
register CHAR *s = Buffer;
register COLP p = Colpts;
int j, c, bline = 0;
for ( ; ; ) {
p->c_ptr0 = p->c_ptr = s;
if (p == &Colpts[Ncols]) return;
(p++)->c_lno = Lnumb + bline;
for (j = (Length - Margin)/Dblspace; --j >= 0; ++bline)
for (Inpos = 0; ; ) {
if ((c = getc(Files->f_f)) == EOF) {
for (*s = EOF; p <= &Colpts[Ncols]; ++p)
p->c_ptr0 = p->c_ptr = s;
balance(bline);
return;
}
if (isprint(c)) ++Inpos;
if (Inpos <= Colw || c == '\n') {
*s = c;
if (++s >= Bufend)
die("page-buffer overflow");
}
if (c == '\n') break;
switch (c) {
case '\b': if (Inpos == 0) --s;
case ESC: if (Inpos > 0) --Inpos;
}
}
}
}
balance(bline) /* line balancing for last page */
{
register CHAR *s = Buffer;
register COLP p = Colpts;
int colno = 0, j, c, l;
c = bline % Ncols;
l = (bline + Ncols - 1)/Ncols;
bline = 0;
do {
for (j = 0; j < l; ++j)
while (*s++ != '\n') ;
(++p)->c_lno = Lnumb + (bline += l);
p->c_ptr0 = p->c_ptr = s;
if (++colno == c) --l;
} while (colno < Ncols - 1);
}
get(colno)
{
static int peekc = 0;
register COLP p;
register FILS *q;
register int c;
if (peekc)
{ peekc = 0; c = Etabc; }
else if (Buffer) {
p = &Colpts[colno];
if (p->c_ptr >= (p+1)->c_ptr0) c = EOF;
else if ((c = *p->c_ptr) != EOF) ++p->c_ptr;
} else if ((c =
(q = &Files[Multi == 'a' ? 0 : colno])->f_nextc) == EOF) {
for (q = &Files[Nfiles]; --q >= Files && q->f_nextc == EOF; ) ;
if (q >= Files) c = '\n';
} else
q->f_nextc = getc(q->f_f);
if (Etabn != 0 && c == Etabc) {
++Inpos;
peekc = ETABS;
c = ' ';
} else if (isprint(c))
++Inpos;
else
switch (c) {
case '\b':
case ESC:
if (Inpos > 0) --Inpos;
break;
case '\f':
if (Ncols == 1) break;
c = '\n';
case '\n':
case '\r':
Inpos = 0;
}
return (C = c);
}
put(c)
{
int move;
switch (c) {
case ' ':
if(Ncols < 2 || Lcolpos < Colw) {
++Nspace;
++Lcolpos;
}
return;
case '\t':
if(Itabn == 0)
break;
if(Lcolpos < Colw) {
move = Itabn - ((Lcolpos + Itabn) % Itabn);
move = (move < Colw-Lcolpos) ? move : Colw-Lcolpos;
Nspace += move;
Lcolpos += move;
}
return;
case '\b':
if (Lcolpos == 0) return;
if (Nspace > 0) { --Nspace; --Lcolpos; return; }
if (Lcolpos > Pcolpos) { --Lcolpos; return; }
case ESC:
move = -1;
break;
case '\n':
++Line;
case '\r':
case '\f':
Pcolpos = 0; Lcolpos = 0; Nspace = 0; Outpos = 0;
default:
move = (isprint(c) != 0);
}
if (Page < Fpage) return;
if (Lcolpos > 0 || move > 0) Lcolpos += move;
putspace();
if (Ncols < 2 || Lcolpos <= Colw) {
putchar(c);
Outpos += move;
Pcolpos = Lcolpos;
}
}
putspace()
{
int nc;
for ( ; Nspace > 0; Outpos += nc, Nspace -= nc)
if (ITABS)
putchar(Itabc);
else {
nc = 1;
putchar(' ');
}
}
atoix(p) register char **p;
{
register int n = 0, c;
while (isdigit(c = *++*p)) n = 10*n + c - '0';
--*p;
return (n);
}
/* Defer message about failure to open file to prevent messing up
alignment of page with tear perforations or form markers.
Treat empty file as special case and report as diagnostic.
*/
#define EMPTY 14 /* length of " -- empty file" */
typedef struct err { struct err *e_nextp; char *e_mess; } ERR;
ERR *Err = NULL, *Lasterr = (ERR *)&Err;
FILE *mustopen(s, f) char *s; register FILS *f;
{
if (*s == '\0') {
f->f_name = STDINNAME();
f->f_f = stdin;
} else if ((f->f_f = fopen(f->f_name = s, "r")) == NULL) {
char *strcpy();
s = ffiler(f->f_name);
s = strcpy((char *)getspace((UNS)(strlen(s) + 1)), s);
}
if (f->f_f != NULL) {
if ((f->f_nextc = getc(f->f_f)) != EOF || Multi == 'm')
return (f->f_f);
sprintf(s = (char *)getspace((UNS)(strlen(f->f_name) + 1 + EMPTY)),
"%s -- empty file", f->f_name);
fclose(f->f_f);
}
Error = 1;
if (Report)
if (Ttyout) { /* accumulate error reports */
Lasterr = Lasterr->e_nextp = (ERR *)getspace((UNS)sizeof(ERR));
Lasterr->e_nextp = NULL;
Lasterr->e_mess = s;
} else { /* ok to print error report now */
cerror(s);
putc('\n', stderr);
}
return ((FILE *)NULL);
}
ANY *getspace(n) UNS n;
{
ANY *t;
if ((t = (ANY *)malloc(n)) == NULL) die("out of space");
return (t);
}
die(s) char *s;
{
++Error;
errprint();
cerror(s);
putc('\n', stderr);
exit(1);
}
onintr()
{
++Error;
errprint();
_exit(1);
}
errprint() /* print accumulated error reports */
{
fflush(stdout);
for ( ; Err != NULL; Err = Err->e_nextp) {
cerror(Err->e_mess);
putc('\n', stderr);
}
done();
}
void
usage()
{
char *usage2 = "[-column [-wwidth] [-a]] [-ect] [-ict] [-drtfp] [+page] [-nsk]";
char *usage3 = "[-ooffset] [-llength] [-sseparator] [-h header] [file ...]";
char *usage4 = "[-m [-wwidth]] [-ect] [-ict] [-drtfp] [+page] [-nsk]";
char *usage5 = "[-ooffset] [-llength] [-sseperator] [-h header] file1 file2 ...";
fprintf(stderr,
"usage: pr %s \\\n %s\n\n pr %s \\\n %s\n",
usage2, usage3, usage4, usage5);
exit(1);
}

32
5bin/sed/Makefile Normal file
View File

@@ -0,0 +1,32 @@
#
# @(#)Makefile 1.1 92/07/30 SMI; from UCB 4.1 85/04/05
#
.KEEP_STATE:
.FRC:
BINS= sed
BINDIR= $(DESTDIR)/usr/5bin
LOCAL_HDRS = sed.h
SRCS= sed0.c sed1.c
OBJS= sed0.o sed1.o
CFLAGS=-O -DS5EMUL
.INIT: $(HDRS) $(LOCAL_HDRS)
bins : $(BINS)
$(LOCAL_BINS) $(BINS) : $$(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LINK_LIBS)
install: $(BINS)
install -d $(BINDIR)
install -s $(BINS) $(BINDIR)
install_h:
clean:
-rm -rf $(LOCAL_BINS) $(BINS) $(LOCAL_LIBS) $(LIBS) $(OBJS) \
core a.out

133
5bin/sed/sed.h Normal file
View File

@@ -0,0 +1,133 @@
/* @(#)sed.h 1.1 92/07/30 SMI; from S5R3.1 1.8 */
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/*
* sed -- stream editor
*
* Copyright 1975 Bell Telephone Laboratories, Incorporated
*
*/
#include <ctype.h>
#include <locale.h>
/*
* define some macros for rexexp.h
*/
#define INIT extern char *cp; /* cp points to RE string */\
register char *sp = cp;
#define GETC() (*sp++)
#define PEEKC() (*sp)
#define UNGETC(c) (--sp)
#define RETURN(c) cp = sp; return(ep);
#define ERROR(c) regerr(c)
#define CEND 16
#define CLNUM 14
#define NLINES 256
#define DEPTH 20
#define PTRSIZE 200
#define RESIZE 10000
#define ABUFSIZE 20
#define LBSIZE 4000
#define ESIZE 256
#define LABSIZE 50
extern union reptr *abuf[];
extern union reptr **aptr;
extern char genbuf[];
extern char *lcomend;
extern long lnum;
extern char linebuf[];
extern char holdsp[];
extern char *spend;
extern char *hspend;
extern int nflag;
extern long tlno[];
#define ACOM 01
#define BCOM 020
#define CCOM 02
#define CDCOM 025
#define CNCOM 022
#define COCOM 017
#define CPCOM 023
#define DCOM 03
#define ECOM 015
#define EQCOM 013
#define FCOM 016
#define GCOM 027
#define CGCOM 030
#define HCOM 031
#define CHCOM 032
#define ICOM 04
#define LCOM 05
#define NCOM 012
#define PCOM 010
#define QCOM 011
#define RCOM 06
#define SCOM 07
#define TCOM 021
#define WCOM 014
#define CWCOM 024
#define YCOM 026
#define XCOM 033
union reptr {
struct reptr1 {
char *ad1;
char *ad2;
char *re1;
char *rhs;
FILE *fcode;
char command;
int gfl;
char pfl;
char inar;
char negfl;
} r1;
struct reptr2 {
char *ad1;
char *ad2;
union reptr *lb1;
char *rhs;
FILE *fcode;
char command;
int gfl;
char pfl;
char inar;
char negfl;
} r2;
};
extern union reptr ptrspace[];
struct label {
char asc[9];
union reptr *chain;
union reptr *address;
};
extern int eargc;
extern union reptr *pending;
char *compile();
char *ycomp();
char *address();
char *text();
char *compsub();
struct label *search();
char *gline();
char *place();

847
5bin/sed/sed0.c Normal file
View File

@@ -0,0 +1,847 @@
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)sed0.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.10 */
#endif
#include <stdio.h>
#include <sys/param.h>
#include "sed.h"
#define NWFILES 11 /* 10 plus one for standard output */
FILE *fin;
FILE *fcode[NWFILES];
char *lastre;
char sseof;
union reptr *ptrend;
int eflag;
extern nbra;
char linebuf[LBSIZE+1];
int gflag;
int nlno;
char *fname[NWFILES];
int nfiles;
union reptr ptrspace[PTRSIZE];
union reptr *rep;
char *cp;
char respace[RESIZE];
struct label ltab[LABSIZE];
struct label *lab;
struct label *labend;
int depth;
int eargc;
char **eargv;
union reptr **cmpend[DEPTH];
#define CCEOF 22
struct label *labtab = ltab;
char ETMES[] = "Extra text at end of command: %s";
char SMMES[] = "Space missing before filename: %s";
char TMMES[] = "Too much command text: %s";
char LTL[] = "Label too long: %s";
char AD0MES[] = "No addresses allowed: %s";
char AD1MES[] = "Only one address allowed: %s";
char TOOBIG[] = "Suffix too large - 512 max: %s";
extern sed; /* IMPORTANT flag !!! */
extern char *comple();
extern char *malloc();
main(argc, argv)
char *argv[];
{
int flag_found = 0;
sed = 1;
eargc = argc;
eargv = argv;
aptr = abuf;
lab = labtab + 1; /* 0 reserved for end-pointer */
rep = ptrspace;
rep->r1.ad1 = respace;
lcomend = &genbuf[71];
ptrend = &ptrspace[PTRSIZE];
labend = &labtab[LABSIZE];
lnum = 0;
pending = 0;
depth = 0;
spend = linebuf;
hspend = holdsp; /* Avoid "bus error" under "H" cmd. */
fcode[0] = stdout;
fname[0] = "";
nfiles = 1;
if(eargc == 1)
exit(0);
setlocale(LC_ALL, ""); /* get locale environment */
while (--eargc > 0 && (++eargv)[0][0] == '-')
switch (eargv[0][1]) {
case 'n':
nflag++;
continue;
case 'f':
flag_found = 1;
if(eargc-- <= 0) exit(2);
if((fin = fopen(*++eargv, "r")) == NULL) {
(void) fprintf(stderr, "sed: ");
perror(*eargv);
exit(2);
}
fcomp();
(void) fclose(fin);
continue;
case 'e':
flag_found = 1;
eflag++;
fcomp();
eflag = 0;
continue;
case 'g':
gflag++;
continue;
default:
(void) fprintf(stderr, "sed: Unknown flag: %c\n", eargv[0][1]);
exit(2);
}
if(rep == ptrspace && !flag_found) {
eargv--;
eargc++;
eflag++;
fcomp();
eargv++;
eargc--;
eflag = 0;
}
if(depth)
comperr("Too many {'s");
labtab->address = rep;
dechain();
if(eargc <= 0)
execute((char *)NULL);
else while(--eargc >= 0) {
execute(*eargv++);
}
(void) fclose(stdout);
exit(0);
/*NOTREACHED*/
}
fcomp()
{
register char *p, *op, *tp;
char *address();
union reptr *pt, *pt1;
int i, ii;
struct label *lpt;
char fnamebuf[MAXPATHLEN];
op = lastre;
if(rline(linebuf, &linebuf[LBSIZE+1]) < 0) return;
if(*linebuf == '#') {
if(linebuf[1] == 'n')
nflag = 1;
}
else {
cp = linebuf;
goto comploop;
}
for(;;) {
if(rline(linebuf, &linebuf[LBSIZE+1]) < 0) break;
cp = linebuf;
comploop:
/* (void) fprintf(stderr, "cp: %s\n", cp); /*DEBUG*/
while(*cp == ' ' || *cp == '\t') cp++;
if(*cp == '\0' || *cp == '#') continue;
if(*cp == ';') {
cp++;
goto comploop;
}
p = address(rep->r1.ad1);
if(p == rep->r1.ad1) {
if(op)
rep->r1.ad1 = op;
else
comperr("First RE may not be null: %s");
} else if(p == 0) {
p = rep->r1.ad1;
rep->r1.ad1 = 0;
} else {
op = rep->r1.ad1;
if(*cp == ',' || *cp == ';') {
cp++;
rep->r1.ad2 = p;
p = address(rep->r1.ad2);
if(p == 0)
comperr("Illegal line number: %s");
if(p == rep->r1.ad2)
rep->r1.ad2 = op;
else
op = rep->r1.ad2;
} else
rep->r1.ad2 = 0;
}
if(p > &respace[RESIZE-1])
comperr(TMMES);
while(*cp == ' ' || *cp == '\t') cp++;
swit:
switch(*cp++) {
default:
comperr("Unrecognized command: %s");
case '!':
rep->r1.negfl = 1;
goto swit;
case '{':
rep->r1.command = BCOM;
rep->r1.negfl = !(rep->r1.negfl);
cmpend[depth++] = &rep->r2.lb1;
if(++rep >= ptrend)
comperr("Too many commands: %s");
rep->r1.ad1 = p;
if(*cp == '\0') continue;
goto comploop;
case '}':
if(rep->r1.ad1)
comperr(AD0MES);
if(--depth < 0)
comperr("Too many }'s");
*cmpend[depth] = rep;
rep->r1.ad1 = p;
continue;
case '=':
rep->r1.command = EQCOM;
if(rep->r1.ad2)
comperr(AD1MES);
break;
case ':':
if(rep->r1.ad1)
comperr(AD0MES);
while(*cp++ == ' ');
cp--;
tp = lab->asc;
while((*tp++ = *cp++))
if(tp >= &(lab->asc[8]))
comperr(LTL);
*--tp = '\0';
if(lpt = search(lab)) {
if(lpt->address)
comperr("Duplicate labels: %s");
} else {
lab->chain = 0;
lpt = lab;
if(++lab >= labend)
comperr("Too many labels: %s");
}
lpt->address = rep;
rep->r1.ad1 = p;
continue;
case 'a':
rep->r1.command = ACOM;
if(rep->r1.ad2)
comperr(AD1MES);
if(*cp == '\\') cp++;
if(*cp++ != '\n')
comperr(ETMES);
rep->r1.re1 = p;
if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
comperr(TMMES);
break;
case 'c':
rep->r1.command = CCOM;
if(*cp == '\\') cp++;
if(*cp++ != ('\n'))
comperr(ETMES);
rep->r1.re1 = p;
if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
comperr(TMMES);
break;
case 'i':
rep->r1.command = ICOM;
if(rep->r1.ad2)
comperr(AD1MES);
if(*cp == '\\') cp++;
if(*cp++ != ('\n'))
comperr(ETMES);
rep->r1.re1 = p;
if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
comperr(TMMES);
break;
case 'g':
rep->r1.command = GCOM;
break;
case 'G':
rep->r1.command = CGCOM;
break;
case 'h':
rep->r1.command = HCOM;
break;
case 'H':
rep->r1.command = CHCOM;
break;
case 't':
rep->r1.command = TCOM;
goto jtcommon;
case 'b':
rep->r1.command = BCOM;
jtcommon:
while(*cp++ == ' ');
cp--;
if(*cp == '\0') {
if(pt = labtab->chain) {
while(pt1 = pt->r2.lb1)
pt = pt1;
pt->r2.lb1 = rep;
} else
labtab->chain = rep;
break;
}
tp = lab->asc;
while((*tp++ = *cp++))
if(tp >= &(lab->asc[8]))
comperr(LTL);
cp--;
*--tp = '\0';
if(lpt = search(lab)) {
if(lpt->address) {
rep->r2.lb1 = lpt->address;
} else {
pt = lpt->chain;
while(pt1 = pt->r2.lb1)
pt = pt1;
pt->r2.lb1 = rep;
}
} else {
lab->chain = rep;
lab->address = 0;
if(++lab >= labend)
comperr("Too many labels: %s");
}
break;
case 'n':
rep->r1.command = NCOM;
break;
case 'N':
rep->r1.command = CNCOM;
break;
case 'p':
rep->r1.command = PCOM;
break;
case 'P':
rep->r1.command = CPCOM;
break;
case 'r':
rep->r1.command = RCOM;
if(rep->r1.ad2)
comperr(AD1MES);
if(*cp++ != ' ')
comperr(SMMES);
rep->r1.re1 = p;
if ((p = text(rep->r1.re1, &respace[RESIZE-1])) == NULL)
comperr(TMMES);
break;
case 'd':
rep->r1.command = DCOM;
break;
case 'D':
rep->r1.command = CDCOM;
rep->r2.lb1 = ptrspace;
break;
case 'q':
rep->r1.command = QCOM;
if(rep->r1.ad2)
comperr(AD1MES);
break;
case 'l':
rep->r1.command = LCOM;
break;
case 's':
rep->r1.command = SCOM;
sseof = *cp++;
rep->r1.re1 = p;
p = comple((char *) 0, rep->r1.re1, &respace[RESIZE-1], sseof);
if(p == rep->r1.re1) {
if(op)
rep->r1.re1 = op;
else
comperr("First RE may not be null: %s");
} else
op = rep->r1.re1;
rep->r1.rhs = p;
p = compsub(rep->r1.rhs);
if(*cp == 'g') {
cp++;
rep->r1.gfl = 999;
} else if(gflag)
rep->r1.gfl = 999;
if(*cp >= '1' && *cp <= '9')
{i = *cp - '0';
cp++;
while(1)
{ii = *cp;
if(ii < '0' || ii > '9') break;
i = i*10 + ii - '0';
if(i > 512)
comperr(TOOBIG);
cp++;
}
rep->r1.gfl = i;
}
if(*cp == 'p') {
cp++;
rep->r1.pfl = 1;
}
if(*cp == 'P') {
cp++;
rep->r1.pfl = 2;
}
if(*cp == 'w') {
cp++;
if(*cp++ != ' ')
comperr(SMMES);
if (text(fnamebuf, &fnamebuf[MAXPATHLEN]) == NULL)
comperr("File name too long: %s");
for(i = nfiles - 1; i >= 0; i--)
if(strcmp(fnamebuf,fname[i]) == 0) {
rep->r1.fcode = fcode[i];
goto done;
}
if(nfiles >= NWFILES)
comperr("Too many files in w commands: %s");
i = strlen(fnamebuf) + 1;
if ((fname[nfiles] = malloc((unsigned)i)) == NULL) {
(void) fprintf(stderr, "sed: Out of memory\n");
exit(2);
}
(void) strcpy(fname[nfiles], fnamebuf);
if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
(void) fprintf(stderr, "sed: Cannot open ");
perror(fname[nfiles]);
exit(2);
}
fcode[nfiles++] = rep->r1.fcode;
}
break;
case 'w':
rep->r1.command = WCOM;
if(*cp++ != ' ')
comperr(SMMES);
if (text(fnamebuf, &fnamebuf[MAXPATHLEN]) == NULL)
comperr("File name too long: %s");
for(i = nfiles - 1; i >= 0; i--)
if(strcmp(fnamebuf, fname[i]) == 0) {
rep->r1.fcode = fcode[i];
goto done;
}
if(nfiles >= NWFILES)
comperr("Too many files in w commands: %s");
i = strlen(fnamebuf) + 1;
if ((fname[nfiles] = malloc((unsigned)i)) == NULL) {
(void) fprintf(stderr, "sed: Out of memory\n");
exit(2);
}
(void) strcpy(fname[nfiles], fnamebuf);
if((rep->r1.fcode = fopen(fname[nfiles], "w")) == NULL) {
(void) fprintf(stderr, "sed: Cannot create ");
perror(fname[nfiles]);
exit(2);
}
fcode[nfiles++] = rep->r1.fcode;
break;
case 'x':
rep->r1.command = XCOM;
break;
case 'y':
rep->r1.command = YCOM;
sseof = *cp++;
rep->r1.re1 = p;
p = ycomp(rep->r1.re1);
break;
}
done:
if(++rep >= ptrend)
comperr("Too many commands, last: %s");
rep->r1.ad1 = p;
if(*cp++ != '\0') {
if(cp[-1] == ';')
goto comploop;
comperr(ETMES);
}
}
rep->r1.command = 0;
lastre = op;
}
char *compsub(rhsbuf)
char *rhsbuf;
{
register char *p, *q;
p = rhsbuf;
q = cp;
for(;;) {
if(p > &respace[RESIZE-1])
comperr(TMMES);
if((*p = *q++) == '\\') {
p++;
if(p > &respace[RESIZE-1])
comperr(TMMES);
*p = *q++;
if(*p > nbra + '0' && *p <= '9')
comperr("``\\digit'' out of range: %s");
p++;
continue;
}
if(*p == sseof) {
*p++ = '\0';
cp = q;
return(p);
}
if(*p++ == '\0')
comperr("Ending delimiter missing on substitution: %s");
}
}
rline(lbuf, lbend)
char *lbuf;
char *lbend;
{
register char *p, *q;
register t;
static char *saveq;
p = lbuf;
if(eflag) {
if(eflag > 0) {
eflag = -1;
if(--eargc <= 0)
exit(2);
q = *++eargv;
while((t = *q++) != '\0') {
if(t == '\n') {
saveq = q;
goto out1;
}
if (p < lbend)
*p++ = t;
if(t == '\\') {
if((t = *q++) == '\0') {
saveq = 0;
return(-1);
}
if (p < lbend)
*p++ = t;
}
}
saveq = 0;
out1:
if (p == lbend)
comperr("Command line too long");
*p = '\0';
return(1);
}
if((q = saveq) == 0) return(-1);
while((t = *q++) != '\0') {
if(t == '\n') {
saveq = q;
goto out2;
}
if(p < lbend)
*p++ = t;
if(t == '\\') {
if((t = *q++) == '\0') {
saveq = 0;
return(-1);
}
if (p < lbend)
*p++ = t;
}
}
saveq = 0;
out2:
if (p == lbend)
comperr("Command line too long");
*p = '\0';
return(1);
}
while((t = getc(fin)) != EOF) {
if(t == '\n') {
if (p == lbend)
comperr("Command line too long");
*p = '\0';
return(1);
}
if (p < lbend)
*p++ = t;
if(t == '\\') {
if((t = getc(fin)) == EOF)
break;
if(p < lbend)
*p++ = t;
}
}
if(ferror(fin)) {
perror("sed: Error reading pattern file");
exit(2);
}
return(-1);
}
char *address(expbuf)
char *expbuf;
{
register char *rcp;
long lno;
if(*cp == '$') {
if (expbuf > &respace[RESIZE-2])
comperr(TMMES);
cp++;
*expbuf++ = CEND;
*expbuf++ = CCEOF;
return(expbuf);
}
if (*cp == '/' || *cp == '\\' ) {
if ( *cp == '\\' )
cp++;
sseof = *cp++;
return(comple((char *) 0, expbuf, &respace[RESIZE-1], sseof));
}
rcp = cp;
lno = 0;
while(*rcp >= '0' && *rcp <= '9')
lno = lno*10 + *rcp++ - '0';
if(rcp > cp) {
if (expbuf > &respace[RESIZE-3])
comperr(TMMES);
*expbuf++ = CLNUM;
*expbuf++ = nlno;
tlno[nlno++] = lno;
if(nlno >= NLINES)
comperr("Too many line numbers: %s");
*expbuf++ = CCEOF;
cp = rcp;
return(expbuf);
}
return(0);
}
char *text(textbuf, tbend)
char *textbuf;
char *tbend;
{
register char *p, *q;
p = textbuf;
q = cp;
#ifndef S5EMUL
/*
* Strip off indentation from text to be inserted.
*/
while(*q == '\t' || *q == ' ') q++;
#endif
for(;;) {
if(p > tbend)
return(NULL); /* overflowed the buffer */
if((*p = *q++) == '\\')
*p = *q++;
if(*p == '\0') {
cp = --q;
return(++p);
}
#ifndef S5EMUL
/*
* Strip off indentation from text to be inserted.
*/
if(*p == '\n') {
while(*q == '\t' || *q == ' ') q++;
}
#endif
p++;
}
}
struct label *search(ptr)
struct label *ptr;
{
struct label *rp;
rp = labtab;
while(rp < ptr) {
if(strcmp(rp->asc, ptr->asc) == 0)
return(rp);
rp++;
}
return(0);
}
dechain()
{
struct label *lptr;
union reptr *rptr, *trptr;
for(lptr = labtab; lptr < lab; lptr++) {
if(lptr->address == 0) {
(void) fprintf(stderr, "sed: Undefined label: %s\n", lptr->asc);
exit(2);
}
if(lptr->chain) {
rptr = lptr->chain;
while(trptr = rptr->r2.lb1) {
rptr->r2.lb1 = lptr->address;
rptr = trptr;
}
rptr->r2.lb1 = lptr->address;
}
}
}
char *ycomp(expbuf)
char *expbuf;
{
register char c;
register char *ep, *tsp;
register int i;
char *sp;
ep = expbuf;
if(ep + 0377 > &respace[RESIZE-1])
comperr(TMMES);
sp = cp;
for(tsp = cp; (c = *tsp) != sseof; tsp++) {
if(c == '\\')
tsp++;
if(c == '\0' || c == '\n')
comperr("Ending delimiter missing on string: %s");
}
tsp++;
while((c = *sp++) != sseof) {
c &= 0377;
if(c == '\\' && *sp == 'n') {
sp++;
c = '\n';
}
if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
ep[c] = '\n';
tsp++;
}
if(ep[c] == sseof || ep[c] == '\0')
comperr("Transform strings not the same size: %s");
}
if(*tsp != sseof) {
if(*tsp == '\0')
comperr("Ending delimiter missing on string: %s");
else
comperr("Transform strings not the same size: %s");
}
cp = ++tsp;
for(i = 0; i < 0400; i++)
if(ep[i] == 0)
ep[i] = i;
return(ep + 0400);
}
comperr(msg)
char *msg;
{
(void) fprintf(stderr, "sed: ");
(void) fprintf(stderr, msg, linebuf);
(void) putc('\n', stderr);
exit(2);
}

727
5bin/sed/sed1.c Normal file
View File

@@ -0,0 +1,727 @@
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)sed1.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.7 */
#endif
#include <stdio.h>
#include "sed.h"
#include <regexp.h>
union reptr *abuf[ABUFSIZE+1];
union reptr **aptr;
char ibuf[BUFSIZ];
char *cbp;
char *ebp;
char genbuf[LBSIZE+1];
char *lcomend;
int dolflag;
int sflag;
int jflag;
int delflag;
long lnum;
char holdsp[LBSIZE+1];
char *spend;
char *hspend;
int nflag;
long tlno[NLINES];
int f;
char *ifname;
int numpass;
union reptr *pending;
char *trans[040] = {
"\\01",
"\\02",
"\\03",
"\\04",
"\\05",
"\\06",
"\\07",
"-<",
"->",
"\n",
"\\13",
"\\14",
"\\15",
"\\16",
"\\17",
"\\20",
"\\21",
"\\22",
"\\23",
"\\24",
"\\25",
"\\26",
"\\27",
"\\30",
"\\31",
"\\32",
"\\33",
"\\34",
"\\35",
"\\36",
"\\37"
};
char rub[] = {"\\177"};
extern char TMMES[];
execute(file)
char *file;
{
register char *p1, *p2;
register union reptr *ipc;
int c;
char *execp;
if (file) {
if ((f = open(file, 0)) < 0) {
(void) fprintf(stderr, "sed: ");
perror(file);
}
ifname = file;
} else {
f = 0;
ifname = "standard input";
}
ebp = ibuf;
cbp = ibuf;
if(pending) {
ipc = pending;
pending = 0;
goto yes;
}
for(;;) {
if((execp = gline(linebuf)) == 0) {
(void) close(f);
return;
}
spend = execp;
for(ipc = ptrspace; ipc->r1.command; ) {
p1 = ipc->r1.ad1;
p2 = ipc->r1.ad2;
if(p1) {
if(ipc->r1.inar) {
if(*p2 == CEND) {
p1 = 0;
} else if(*p2 == CLNUM) {
c = (unsigned char)p2[1];
if(lnum > tlno[c]) {
ipc->r1.inar = 0;
if(ipc->r1.negfl)
goto yes;
ipc++;
continue;
}
if(lnum == tlno[c]) {
ipc->r1.inar = 0;
}
} else if(match(p2, 0)) {
ipc->r1.inar = 0;
}
} else if(*p1 == CEND) {
if(!dolflag) {
if(ipc->r1.negfl)
goto yes;
ipc++;
continue;
}
} else if(*p1 == CLNUM) {
c = (unsigned char)p1[1];
if(lnum != tlno[c]) {
if(ipc->r1.negfl)
goto yes;
ipc++;
continue;
}
if(p2)
ipc->r1.inar = 1;
} else if(match(p1, 0)) {
if(p2)
ipc->r1.inar = 1;
} else {
if(ipc->r1.negfl)
goto yes;
ipc++;
continue;
}
}
if(ipc->r1.negfl) {
ipc++;
continue;
}
yes:
command(ipc);
if(delflag)
break;
if(jflag) {
jflag = 0;
if((ipc = ipc->r2.lb1) == 0) {
ipc = ptrspace;
break;
}
} else
ipc++;
}
if(!nflag && !delflag) {
for(p1 = linebuf; p1 < spend; p1++)
(void) putc(*p1, stdout);
(void) putc('\n', stdout);
}
if(aptr > abuf) {
arout();
}
delflag = 0;
}
}
match(expbuf, gf)
char *expbuf;
{
register char *p1;
if(gf) {
if(*expbuf) return(0);
locs = p1 = loc2;
} else {
p1 = linebuf;
locs = 0;
}
circf = *expbuf++;
return(step(p1, expbuf));
}
substitute(ipc)
union reptr *ipc;
{
if(match(ipc->r1.re1, 0) == 0) return(0);
numpass = 0;
sflag = 0; /* Flags if any substitution was made */
dosub(ipc->r1.rhs, ipc->r1.gfl);
if(ipc->r1.gfl) {
while(*loc2) {
if(match(ipc->r1.re1, 1) == 0) break;
dosub(ipc->r1.rhs, ipc->r1.gfl);
}
}
return(sflag);
}
dosub(rhsbuf,n)
char *rhsbuf;
int n;
{
register char *lp, *sp, *rp;
int c;
if(n > 0 && n < 999)
{numpass++;
if(n != numpass) return;
}
sflag = 1;
lp = linebuf;
sp = genbuf;
rp = rhsbuf;
while (lp < loc1)
*sp++ = *lp++;
while(c = *rp++) {
if (c == '&')
sp = place(sp, loc1, loc2);
else if (c == '\\') {
c = *rp++;
if (c >= '1' && c < NBRA+'1')
sp = place(sp, braslist[c-'1'], braelist[c-'1']);
else
*sp++ = c;
} else
*sp++ = c;
if (sp == &genbuf[LBSIZE+1]) {
(void) fprintf(stderr, "Output line too long.\n");
*--sp = '\0';
goto out;
}
}
lp = loc2;
loc2 = sp - genbuf + linebuf;
while(*sp++ = *lp++)
if (sp == &genbuf[LBSIZE+1]) {
(void) fprintf(stderr, "Output line too long.\n");
*--sp = '\0';
break;
}
out:
lp = linebuf;
sp = genbuf;
while (*lp++ = *sp++);
spend = lp-1;
}
char *place(asp, al1, al2)
char *asp, *al1, *al2;
{
register char *sp, *l1, *l2;
sp = asp;
l1 = al1;
l2 = al2;
while (l1 < l2) {
*sp++ = *l1++;
if (sp == &genbuf[LBSIZE+1])
break;
}
return(sp);
}
command(ipc)
union reptr *ipc;
{
register int i;
register char *p1, *p2, *p3;
char *execp;
switch(ipc->r1.command) {
case ACOM:
if(aptr >= &abuf[ABUFSIZE]) {
(void) fprintf(stderr, "Too many appends or reads after line %ld\n",
lnum);
} else {
*aptr++ = ipc;
*aptr = 0;
}
break;
case CCOM:
delflag = 1;
if(!ipc->r1.inar || dolflag) {
for(p1 = ipc->r1.re1; *p1; )
(void) putc(*p1++, stdout);
(void) putc('\n', stdout);
}
break;
case DCOM:
delflag++;
break;
case CDCOM:
p1 = p2 = linebuf;
while(*p1 != '\n') {
if(*p1++ == 0) {
delflag++;
return;
}
}
p1++;
while(*p2++ = *p1++);
spend = p2-1;
jflag++;
break;
case EQCOM:
(void) fprintf(stdout, "%ld\n", lnum);
break;
case GCOM:
p1 = linebuf;
p2 = holdsp;
while(*p1++ = *p2++);
spend = p1-1;
break;
case CGCOM:
*spend++ = '\n';
p1 = spend;
p2 = holdsp;
do {
if (p1 == &linebuf[LBSIZE+1]) {
(void) fprintf(stderr, "Output line too long.\n");
*--p1 = '\0';
}
} while(*p1++ = *p2++);
spend = p1-1;
break;
case HCOM:
p1 = holdsp;
p2 = linebuf;
while(*p1++ = *p2++);
hspend = p1-1;
break;
case CHCOM:
*hspend++ = '\n';
p1 = hspend;
p2 = linebuf;
do {
if (p1 == &holdsp[LBSIZE+1]) {
(void) fprintf(stderr, "Hold space overflowed.\n");
*--p1 = '\0';
}
} while(*p1++ = *p2++);
hspend = p1-1;
break;
case ICOM:
for(p1 = ipc->r1.re1; *p1; )
(void) putc(*p1++, stdout);
(void) putc('\n', stdout);
break;
case BCOM:
jflag = 1;
break;
case LCOM:
p1 = linebuf;
p2 = genbuf;
genbuf[72] = 0;
while(*p1)
if((unsigned char)*p1 >= 040) {
if(*p1 == 0177) {
p3 = rub;
while(*p2++ = *p3++)
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
p2--;
p1++;
continue;
}
if(!isprint(*p1 & 0377)) {
*p2++ = '\\';
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
*p2++ = (*p1 >> 6) + '0';
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
*p2++ = ((*p1 >> 3) & 07) + '0';
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
*p2++ = (*p1++ & 07) + '0';
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
} else {
*p2++ = *p1++;
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
}
} else {
p3 = trans[(unsigned char)*p1-1];
while(*p2++ = *p3++)
if(p2 >= lcomend) {
*p2 = '\\';
(void) fprintf(stdout, "%s\n", genbuf);
p2 = genbuf;
}
p2--;
p1++;
}
*p2 = 0;
(void) fprintf(stdout, "%s\n", genbuf);
break;
case NCOM:
if(!nflag) {
for(p1 = linebuf; p1 < spend; p1++)
(void) putc(*p1, stdout);
(void) putc('\n', stdout);
}
if(aptr > abuf)
arout();
if((execp = gline(linebuf)) == 0) {
pending = ipc;
delflag = 1;
break;
}
spend = execp;
break;
case CNCOM:
if(aptr > abuf)
arout();
*spend++ = '\n';
if((execp = gline(spend)) == 0) {
pending = ipc;
delflag = 1;
break;
}
spend = execp;
break;
case PCOM:
for(p1 = linebuf; p1 < spend; p1++)
(void) putc(*p1, stdout);
(void) putc('\n', stdout);
break;
case CPCOM:
cpcom:
for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
(void) putc(*p1++, stdout);
(void) putc('\n', stdout);
break;
case QCOM:
if(!nflag) {
for(p1 = linebuf; p1 < spend; p1++)
(void) putc(*p1, stdout);
(void) putc('\n', stdout);
}
if(aptr > abuf) arout();
(void) fclose(stdout);
exit(0);
case RCOM:
if(aptr >= &abuf[ABUFSIZE]) {
(void) fprintf(stderr, "Too many appends or reads after line %ld\n",
lnum);
} else {
*aptr++ = ipc;
*aptr = 0;
}
break;
case SCOM:
i = substitute(ipc);
if(ipc->r1.pfl && nflag && i)
if(ipc->r1.pfl == 1) {
for(p1 = linebuf; p1 < spend; p1++)
(void) putc(*p1, stdout);
(void) putc('\n', stdout);
}
else
goto cpcom;
if(i && ipc->r1.fcode)
goto wcom;
break;
case TCOM:
if(sflag == 0) break;
sflag = 0;
jflag = 1;
break;
wcom:
case WCOM:
(void) fprintf(ipc->r1.fcode, "%s\n", linebuf);
(void) fflush(ipc->r1.fcode);
break;
case XCOM:
p1 = linebuf;
p2 = genbuf;
while(*p2++ = *p1++);
p1 = holdsp;
p2 = linebuf;
while(*p2++ = *p1++);
spend = p2 - 1;
p1 = genbuf;
p2 = holdsp;
while(*p2++ = *p1++);
hspend = p2 - 1;
break;
case YCOM:
p1 = linebuf;
p2 = ipc->r1.re1;
while(*p1 = p2[(unsigned char)*p1]) p1++;
break;
}
}
char *gline(addr)
char *addr;
{
register char *p1, *p2;
register c;
sflag = 0;
p1 = addr;
p2 = cbp;
for (;;) {
if (p2 >= ebp) {
if(f < 0 || (c = read(f, ibuf, BUFSIZ)) == 0) {
return(0);
}
if(c < 0) {
(void) fprintf(stderr, "sed: error reading ");
perror(ifname);
exit(2);
}
p2 = ibuf;
ebp = ibuf+c;
}
if ((c = *p2++) == '\n') {
if(p2 >= ebp) {
if(f < 0 || (c = read(f, ibuf, BUFSIZ)) == 0) {
if(f >= 0) {
(void) close(f);
f = -1;
}
if(eargc == 0)
dolflag = 1;
}
if(c < 0) {
(void) fprintf(stderr, "sed: error reading ");
perror(ifname);
exit(2);
}
p2 = ibuf;
ebp = ibuf + c;
}
break;
}
if(c)
if(p1 < &linebuf[LBSIZE])
*p1++ = c;
}
lnum++;
*p1 = 0;
cbp = p2;
return(p1);
}
char *comple(x1, ep, x3, x4)
char *x1, *x3;
char x4;
register char *ep;
{
register char *p;
p = compile(x1, ep + 1, x3, x4);
if(p == ep + 1)
return(ep);
*ep = circf;
return(p);
}
regerr(err)
register err;
{
switch(err) {
case 11:
comperr("Range endpoint too large: %s");
break;
case 16:
comperr("Bad number: %s");
break;
case 25:
comperr("``\\digit'' out of range: %s");
break;
case 36:
comperr("Illegal or missing delimiter: %s");
break;
case 41:
comperr("No remembered search string: %s");
break;
case 42:
comperr("\\( \\) imbalance: %s");
break;
case 43:
comperr("Too many \\(: %s");
break;
case 44:
comperr("More than 2 numbers given in \\{ \\}: %s");
break;
case 45:
comperr("} expected after \\: %s");
break;
case 46:
comperr("First number exceeds second in \\{ \\}: %s");
break;
case 49:
comperr("[ ] imbalance: %s");
break;
case 50:
comperr(TMMES);
break;
default:
(void) fprintf(stderr, "Unknown regexp error code %d: %s\n",
err, linebuf);
exit(2);
break;
}
}
arout()
{
register char *p1;
FILE *fi;
char c;
int t;
aptr = abuf - 1;
while(*++aptr) {
if((*aptr)->r1.command == ACOM) {
for(p1 = (*aptr)->r1.re1; *p1; )
(void) putc(*p1++, stdout);
(void) putc('\n', stdout);
} else {
if((fi = fopen((*aptr)->r1.re1, "r")) == NULL)
continue;
while((t = getc(fi)) != EOF) {
c = t;
(void) putc(c, stdout);
}
(void) fclose(fi);
}
}
aptr = abuf;
*aptr = 0;
}

85
5bin/sum.c Normal file
View File

@@ -0,0 +1,85 @@
#ifndef lint
static char sccsid[] = "@(#)sum.c 1.1 92/07/30 SMI"; /* from S5R2 1.5 */
#endif
/*
* Sum bytes in file mod 2^16
*/
#define WDMSK 0177777L
#define BUFSIZE 512
#include <stdio.h>
struct part {
short unsigned hi,lo;
};
union hilo { /* this only works right in case short is 1/2 of long */
struct part hl;
long lg;
} tempa, suma;
main(argc,argv)
char **argv;
{
register unsigned sum;
register i, c;
register FILE *f;
register long nbytes;
int alg, ca, errflg = 0;
unsigned lsavhi,lsavlo;
alg = 0;
i = 1;
if (argc >= 2) {
if(argv[1][0]=='-' && argv[1][1]=='r') {
alg = 1;
i = 2;
}
}
do {
if(i < argc) {
if((f = fopen(argv[i], "r")) == NULL) {
(void) fprintf(stderr, "sum: Can't open %s\n", argv[i]);
errflg += 10;
continue;
}
} else
f = stdin;
sum = 0;
suma.lg = 0;
nbytes = 0;
if(alg == 1) {
while((c = getc(f)) != EOF) {
nbytes++;
if(sum & 01)
sum = (sum >> 1) + 0x8000;
else
sum >>= 1;
sum += c;
sum &= 0xFFFF;
}
} else {
while((ca = getc(f)) != EOF) {
nbytes++;
suma.lg += ca & WDMSK;
}
}
if(ferror(f)) {
errflg++;
(void) fprintf(stderr, "sum: read error on %s\n", argc>1?argv[i]:"-");
}
if (alg == 1)
(void) printf("%.5u%6ld", sum, (nbytes+BUFSIZE-1)/BUFSIZE);
else {
tempa.lg = (suma.hl.lo & WDMSK) + (suma.hl.hi & WDMSK);
lsavhi = (unsigned) tempa.hl.hi;
lsavlo = (unsigned) tempa.hl.lo;
(void) printf("%u %ld", (unsigned)(lsavhi + lsavlo), (nbytes+BUFSIZE-1)/BUFSIZE);
}
if(argc > 1)
(void) printf(" %s", argv[i]==(char *)0?"":argv[i]);
(void) printf("\n");
(void) fclose(f);
} while(++i < argc);
exit(errflg);
/* NOTREACHED */
}

595
5bin/tabs.c Normal file
View File

@@ -0,0 +1,595 @@
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef lint
static char sccsid[] = "@(#)tabs.c 1.1 92/07/30 SMI"; /* from S5R3 1.8 */
#endif
/*
* tabs [tabspec] [+mn] [-Ttype]
* set tabs (and margin, if +mn), for terminal type
*/
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <curses.h>
#include <term.h>
#ifdef u370
#include <sys/ioctl.h>
#include <sys/fepterm.h>
#include <sys/tabs.h>
#endif
#define EQ(a,b) (strcmp(a, b) == 0)
/* max # columns used (needed for GSI) */
#define NCOLS 256
#define NTABS 65 /* max # tabs +1 (to be set) */
#define NTABSCL 21 /* max # tabs + 1 that will be cleared */
#define ESC 033
#define CLEAR '2'
#define SET '1'
#define TAB '\t'
#define CR '\r'
#define NMG 0 /* no margin setting */
#define GMG 1 /* DTC300s margin */
#define TMG 2 /* TERMINET margin */
#define DMG 3 /* DASI450 margin */
#define FMG 4 /* TTY 43 margin */
#define TRMG 5 /* Trendata 4000a */
#define TCLRLN 0 /* long, repetitive, general tab clear */
char tsethp[] = {ESC,'1',0}; /* (default) */
char tsetibm[] = {ESC,'0',0}; /* ibm */
char tclrhp[] = {ESC,'3',CR,0}; /* hp terminals */
char tclrsh[] = {ESC,CLEAR,CR,0}; /* short sequence for many terminals */
char tclrgs[] = {ESC,TAB,CR,0}; /* short, for 300s */
char tclr40[] = {ESC,'R',CR,0}; /* TTY 40/2, 4424 */
char tclribm[] = {ESC,'1',CR,0}; /* ibm */
struct ttab {
char *ttype; /* -Tttype */
char *tclr; /* char sequence to clear tabs and return carriage */
int tmaxtab; /* maximum allowed position */
} *tt;
struct ttab termtab[] = {
"", tclrsh, 132,
"1620-12", tclrsh, 158,
"1620-12-8", tclrsh, 158,
"1700-12", tclrsh, 132,
"1700-12-8", tclrsh, 158,
"300-12", TCLRLN, 158,
"300s-12", tclrgs, 158,
"4424", tclr40, 80,
"4000a", tclrsh, 132,
"4000a-12", tclrsh, 158,
"450-12", tclrsh, 158,
"450-12-8", tclrsh, 158,
"2631", tclrhp, 240,
"2631-c", tclrhp, 240,
"ibm", tclribm, 80,
0
};
int err;
int tmarg, getmarg();
int ttp;
char settab[32], clear_tabs[32];
int maxtab; /* max tab for repetitive spec */
int margin;
int margflg; /* >0 ==> +m option used, 0 ==> not */
char *terminal = "";
char *tabspec = "-8"; /* default tab specification */
struct termio ttyold; /* tty table */
int ttyisave; /* save for input modes */
int ttyosave; /* save for output modes */
int istty; /* 1 ==> is actual tty */
struct stat statbuf;
char *devtty;
int endup();
char *getenv();
struct ttab *termadj();
main(argc, argv)
char **argv;
{
int tabvect[NTABS]; /* build tab list here */
char *ttyname();
char *scan; /* scan pointer to next char */
int endup();
signal(SIGINT, endup);
if (ioctl(1, TCGETA, &ttyold) == 0) {
ttyisave = ttyold.c_iflag;
ttyosave = ttyold.c_oflag;
fstat(1, &statbuf);
devtty = ttyname(1);
chmod(devtty, 0000); /* nobody, not even us */
istty++;
}
tabvect[0] = 0; /* mark as not yet filled in */
while (--argc > 0) {
scan = *++argv;
if (*scan == '+')
switch (*++scan) {
case 'm':
margflg++;
if (*++scan)
margin = getnum(&scan);
else
margin = 10;
break;
}
else if (*scan == '-' && *(scan+1) == 'T')
terminal = scan+2;
else
tabspec = scan; /* save tab specification */
}
if (*terminal == '\0') {
if ((terminal = getenv("TERM")) == NULL) {
fprintf(stderr, "tabs: No terminal type variable TERM in the environment\n");
exit(1);
}
}
#ifdef pdp11
if(*terminal == '\0') err = -1; /*setupterm (libcurses/terminfo) problem on pdp11*/
else /*doesn't detect error if terminal is null*/
#endif
setupterm(terminal,1,&err);
if (err <= 0 || columns <= 0 || set_tab == 0) {
tt = termadj();
if (strcmp(terminal,"ibm") == 0)
strcpy(settab,tsetibm);
else
strcpy(settab,tsethp);
strcpy(clear_tabs,tt->tclr);
maxtab = tt->tmaxtab;
}
else {
maxtab = columns;
strcpy(settab,set_tab);
strcpy(clear_tabs,clear_all_tabs);
}
scantab(tabspec,tabvect,0);
if (!tabvect[0])
repetab("8",tabvect);
#ifdef u370
if((ttyosave & TABDLY) == TAB3)
softtabs(tabvect) ;
else
#endif
settabs(tabvect);
endup();
exit(0);
/* NOTREACHED */
}
/* scantab: scan 1 tabspec & return tab list for it */
scantab(scan,tabvect,level)
char *scan;
int tabvect[NTABS], level;
{
register char c;
if (*scan == '-')
if ((c = *++scan) == '-')
filetab(++scan,tabvect,level);
else if (c >= '0' && c <= '9')
repetab(scan,tabvect);
else if (stdtab(scan,tabvect))
error("unknown tab code");
else;
else
arbitab(scan,tabvect);
}
/* repetab: scan and set repetitve tabs, 1+n, 1+2*n, etc */
repetab(scan,tabvect)
char *scan;
int tabvect[NTABS];
{
register incr, i, tabn;
int limit;
incr = getnum(&scan);
tabn = 1;
limit = (maxtab-1)/(incr?incr:1)-1; /* # last actual tab */
if (limit>NTABS-2)
limit = NTABS-2;
for (i = 0; i<=limit; i++)
tabvect[i] = tabn += incr;
tabvect[i] = 0;
}
/* arbitab: handle list of arbitrary tabs */
arbitab(scan,tabvect)
char *scan;
int tabvect[NTABS];
{
register i, t, last;
last = 0;
for (i = 0; i<NTABS-1;) {
if (*scan == '+') {
scan++; /* +n ==> increment, not absolute */
if (t = getnum(&scan))
tabvect[i++] = last += t;
else error("illegal increment");
}
else {
if ((t = getnum(&scan)) > last)
tabvect[i++] = last = t;
else error("illegal tabs");
}
if (*scan++ != ',') break;
}
if (last > NCOLS)
error("illegal tabs");
tabvect[i] = 0;
}
/* filetab: copy tabspec from existing file */
#define CARDSIZ 132
filetab(scan,tabvect,level)
char *scan;
int tabvect[NTABS];
{
register length, i;
register char c;
int fildes;
char card[CARDSIZ]; /* buffer area for 1st card in file */
char state, found;
char *temp;
if (level)
error("file indirection");
if ((fildes = open(scan,0)) < 0)
error("can't open");
length = read(fildes,card,CARDSIZ);
close(fildes);
found = state = 0;
scan = 0;
for (i = 0; i<length && (c = card[i]) != '\n'; i++) {
switch (state) {
case 0:
state = (c == '<'); break;
case 1:
state = (c == ':')?2:0; break;
case 2:
if (c == 't')
state = 3;
else if (c == ':')
state = 6;
else if (c != ' ')
state = 5;
break;
case 3:
if (c == ' ')
state = 2;
else {
scan = &card[i];
state = 4;
}
break;
case 4:
if (c == ' ') {
card[i] = '\0';
state = 5;
}
else if (c == ':') {
card[i] = '\0';
state = 6;
}
break;
case 5:
if (c == ' ')
state = 2;
else if (c == ':')
state = 6;
break;
case 6:
if (c == '>') {
found = 1;
goto done;
}
else state = 5;
break;
}
}
done:
if (found && scan != 0) {
scantab(scan,tabvect,1);
temp = scan;
while (*++temp);
*temp = '\n';
}
else scantab("-8",tabvect,1);
}
int
getmarg (term)
char *term;
{
if (strncmp(term,"1620",4) == 0 || strncmp(term,"1700",4) == 0 || strncmp(term,"450",3) == 0)
return(DMG);
else if (strncmp(term,"300s",4) == 0)
return(GMG);
else if (strncmp(term,"4000a",5) == 0)
return(TRMG);
else if (strcmp(term,"43") == 0)
return(FMG);
else if (strcmp(term,"tn300") == 0 || strcmp(term,"tn1200") == 0)
return(TMG);
else return(NMG);
}
struct ttab *
termadj()
{
register struct ttab *t;
if (strncmp(terminal,"40-2",4) == 0
|| strncmp(terminal,"40/2",4) == 0
|| strncmp(terminal,"4420",4) == 0)
strcpy(terminal,"4424");
else if (strncmp(terminal,"ibm",3) == 0
|| strcmp(terminal,"3101") == 0
|| strcmp(terminal,"system1") == 0)
strcpy(terminal,"ibm");
for (t = termtab; t->ttype; t++) {
if (EQ(terminal, t->ttype))
return(t);
}
/* should have message */
return(termtab);
}
char *cleartabs();
/* settabs: set actual tabs at terminal */
/* note: this code caters to necessities of handling GSI and
other terminals in a consistent way. */
settabs(tabvect)
int tabvect[NTABS];
{
char setbuf[512]; /* 2+3*NTABS+2+NCOLS+NTABS (+ some extra) */
register char *p; /* ptr for assembly in setbuf */
register *curtab; /* ptr to tabvect item */
int i, previous, nblanks;
if (istty) {
ttyold.c_iflag &= ~ICRNL ;
ttyold.c_oflag &= ~(ONLCR|OCRNL|ONOCR|ONLRET);
ioctl(1, TCSETAW, &ttyold); /* turn off cr-lf map */
}
p = setbuf;
*p++ = CR;
p = cleartabs(p, clear_tabs);
if (margflg) {
tmarg = getmarg(terminal);
switch(tmarg) {
case GMG: /* GSI300S */
/* NOTE: the 300S appears somewhat odd, in that there is
a column 0, but there is no way to do a direct tab to it.
The sequence ESC 'T' '\0' jumps to column 27 and prints
a '0', without changing the margin. */
*p++ = ESC;
*p++ = 'T'; /* setup for direct tab */
if (margin &= 0177) /* normal case */
*p++ = margin;
else { /* +m0 case */
*p++ = 1; /* column 1 */
*p++ = '\b'; /* column 0 */
}
*p++ = margin; /* direct horizontal tab */
*p++ = ESC;
*p++ = '0'; /* actual margin set */
break;
case TMG: /* TERMINET 300 & 1200 */
while (margin--)
*p++ = ' ';
break;
case DMG: /* DASI450/DIABLO 1620 */
*p++ = ESC; /* direct tab ignores margin */
*p++ = '\t';
if (margin == 3){
*p++ = (margin & 0177);
*p++ = ' ';
}
else
*p++ = (margin & 0177) + 1;
*p++ = ESC;
*p++ = '9';
break;
case FMG: /* TTY 43 */
p--;
*p++ = ESC;
*p++ = 'x';
*p++ = CR;
while (margin--)
*p++ = ' ';
*p++ = ESC;
*p++ = 'l';
*p++ = CR;
write(1, setbuf, p - setbuf);
return;
case TRMG:
p--;
*p++ = ESC;
*p++ = 'N';
while (margin--)
*p++ = ' ';
*p++ = ESC;
*p++ = 'F';
break;
}
}
/*
* actual setting: at least terminals do this consistently!
*/
previous = 1; curtab = tabvect;
while ((nblanks = *curtab-previous) >= 0 &&
previous + nblanks <= maxtab) {
for (i = 1; i <= nblanks; i++) *p++ = ' ';
previous = *curtab++;
strcpy(p,settab);
p += strlen(settab);
}
*p++ = CR;
if (EQ(terminal,"4424"))
*p++ = '\n'; /* TTY40/2 needs LF, not just CR */
write(1, setbuf, p - setbuf);
}
/* Set software tabs. This only works on UNIX/370 using a series/1
* front-end processor.
*/
#ifdef u370
softtabs(tabvect)
register int tabvect[] ;
{
htbuf_t hbuf ;
register int i ;
hbuf.ht_line = maxtab ;
i = 0 ;
do{
hbuf.ht_tabs[i] = tabvect[i] ;
}while(tabvect[i++] != 0) ;
hbuf.ht_ntabs = i ;
if(ioctl(1, U370TABS, &hbuf) == -1){
fprintf(stderr, "Error return from ioctl.\n") ;
perror("tabs") ;
}
}
#endif
/* cleartabs(pointer to buffer, pointer to clear sequence) */
char *cleartabs(p, qq)
register char *p;
char *qq;
{
register i;
register char *q;
q = qq;
if (clear_tabs <= 0) { /* if repetitive sequence */
*p++ = CR;
for(i = 0; i < NTABSCL - 1; i++) {
*p++ = TAB;
*p++ = ESC;
*p++ = CLEAR;
}
*p++ = CR;
}
else {
while(*p++ = *q++); /* copy table sequence */
p--; /* adjust for null */
if (EQ(terminal,"4424")) { /* TTY40 extra delays needed */
*p++ = '\0';
*p++ = '\0';
*p++ = '\0';
*p++ = '\0';
}
}
return(p);
}
/* getnum: scan and convert number, return zero if none found */
/* set scan ptr to addr of ending delimeter */
getnum(scan1)
char **scan1;
{
register n;
register char c, *scan;
n = 0;
scan = *scan1;
while ((c = *scan++) >= '0' && c <= '9') n = n * 10 + c -'0';
*scan1 = --scan;
return(n);
}
/* error: terminate processing with message to terminal */
error(arg)
char *arg;
{
register char *temp;
temp = arg;
while (*++temp); /* get length */
*temp = '\n';
endup();
write(2, arg, temp+1-arg);
exit(1);
}
/* endup: make sure tty mode reset & exit */
endup()
{
if (istty) {
ttyold.c_iflag = ttyisave;
ttyold.c_oflag = ttyosave;
ioctl(1, TCSETAW, &ttyold); /* reset cr-lf to previous */
chmod(devtty, statbuf.st_mode & 0777);
}
if (err > 0)
resetterm();
}
/* stdtabs: standard tabs table
format: option code letter(s), null, tabs, null */
char stdtabs[] = {
'a', 0,1,10,16,36,72,0, /* IBM 370 Assembler */
'a','2',0,1,10,16,40,72,0, /* IBM Assembler alternative*/
'c', 0,1,8,12,16,20,55,0, /* COBOL, normal */
'c','2',0,1,6,10,14,49,0, /* COBOL, crunched*/
'c','3',0,1,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62,67,0,
/* crunched COBOL, many tabs */
'f', 0,1,7,11,15,19,23,0, /* FORTRAN */
'p', 0,1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,0, /* PL/I */
's', 0,1,10,55,0, /* SNOBOL */
'u', 0,1,12,20,44,0, /* UNIVAC ASM */
0};
/* stdtab: return tab list for any "canned" tab option.
entry: option points to null-terminated option string
tabvect points to vector to be filled in
exit: return(0) if legal, tabvect filled, ending with zero
return(-1) if unknown option
*/
stdtab(option,tabvect)
char option[];
int tabvect[];
{
register char *sp;
tabvect[0] = 0;
sp = stdtabs;
while (*sp) {
if (EQ(option,sp)) {
while (*sp++); /* skip to 1st tab value */
while (*tabvect++ = *sp++); /* copy, make int */
return(0);
}
while(*sp++); /* skip to 1st tab value */
while(*sp++); /* skip over tab list */
}
return(-1);
}

96
5bin/time.c Normal file
View File

@@ -0,0 +1,96 @@
#ifndef lint
static char sccsid[] = "@(#)time.c 1.1 92/07/30 SMI"; /* from S5R2 1.3 */
#endif
/*
** Time a command
*/
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/param.h> /* HZ defined here */
main(argc, argv)
char **argv;
{
struct {
long user;
long sys;
long childuser;
long childsys;
} buffer;
register p;
extern errno;
extern char *sys_errlist[];
int status;
long before, after;
extern long times();
before = times(&buffer);
if(argc<=1)
exit(0);
p = fork();
if(p == -1) {
fprintf(stderr,"time: cannot fork -- try again.\n");
exit(2);
}
if(p == 0) {
/* close(1); lem commented this out */
execvp(argv[1], &argv[1]);
fprintf(stderr, "%s: %s\n", sys_errlist[errno], argv[1]);
exit(2);
}
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
while(wait(&status) != p);
if((status & 0377) != '\0')
fprintf(stderr,"time: command terminated abnormally.\n");
after = times(&buffer);
fprintf(stderr,"\n");
printt("real", (after-before));
printt("user", buffer.childuser);
printt("sys ", buffer.childsys);
exit(status >> 8);
/* NOTREACHED */
}
/*
The following use of HZ/10 will work correctly only if HZ is a multiple
of 10. However the only values for HZ now in use are 100 for the 3B
and 60 for other machines.
*/
char quant[] = { HZ/10, 10, 10, 6, 10, 6, 10, 10, 10 };
char *pad = "000 ";
char *sep = "\0\0.\0:\0:\0\0";
char *nsep = "\0\0.\0 \0 \0\0";
printt(s, a)
char *s;
long a;
{
register i;
char digit[9];
char c;
int nonzero;
for(i=0; i<9; i++) {
digit[i] = a % quant[i];
a /= quant[i];
}
fprintf(stderr,s);
nonzero = 0;
while(--i>0) {
c = digit[i]!=0 ? digit[i]+'0':
nonzero ? '0':
pad[i];
if (c != '\0')
putc (c, stderr);
nonzero |= digit[i];
c = nonzero?sep[i]:nsep[i];
if (c != '\0')
putc (c, stderr);
}
fprintf(stderr,"\n");
}

151
5bin/tr.c Normal file
View File

@@ -0,0 +1,151 @@
#ifndef lint
static char sccsid[] = "@(#)tr.c 1.1 92/07/30 SMI"; /* from S5R2 1.3 */
#endif
#include <stdio.h>
/* tr - transliterate data stream */
int dflag = 0;
int sflag = 0;
int cflag = 0;
int save = 0;
char code[256];
char squeez[256];
char vect[256];
struct string { int last, max, rep; char *p; } string1, string2;
main(argc,argv)
char **argv;
{
register i;
int j;
register c, d;
char *compl;
register FILE *input;
string1.last = string2.last = 0;
string1.max = string2.max = 0;
string1.rep = string2.rep = 0;
string1.p = string2.p = "";
if(--argc>0) {
argv++;
if(*argv[0]=='-'&&argv[0][1]!=0) {
while(*++argv[0])
switch(*argv[0]) {
case 'c':
cflag++;
continue;
case 'd':
dflag++;
continue;
case 's':
sflag++;
continue;
}
argc--;
argv++;
}
}
if(argc>0) string1.p = argv[0];
if(argc>1) string2.p = argv[1];
for(i=0; i<256; i++)
code[i] = vect[i] = 0;
if(cflag) {
while(c = next(&string1))
vect[c&0377] = 1;
j = 0;
for(i=1; i<256; i++)
if(vect[i]==0) vect[j++] = i;
vect[j] = 0;
compl = vect;
}
for(i=0; i<256; i++)
squeez[i] = 0;
for(;;){
if(cflag) c = *compl++;
else c = next(&string1);
if(c==0) break;
d = next(&string2);
if(d==0) d = c;
code[c&0377] = d;
squeez[d&0377] = 1;
}
while(d = next(&string2))
squeez[d&0377] = 1;
squeez[0] = 1;
for(i=0;i<256;i++) {
if(code[i]==0) code[i] = i;
else if(dflag) code[i] = 0;
}
input = stdin;
while((c=getc(input)) != EOF ) {
if(c == 0) continue;
if(c = code[c&0377]&0377)
if(!sflag || c!=save || !squeez[c&0377])
putchar(save = c);
}
exit(0);
/* NOTREACHED */
}
next(s)
struct string *s;
{
int a, b, c, n;
int base;
if(--s->rep > 0) return(s->last);
if(s->last < s->max) return(++s->last);
if(*s->p=='[') {
nextc(s);
s->last = a = nextc(s);
s->max = 0;
switch(nextc(s)) {
case '-':
b = nextc(s);
if(b<a || *s->p++!=']')
goto error;
s->max = b;
return(a);
case '*':
base = (*s->p=='0')?8:10;
n = 0;
while((c = *s->p)>='0' && c<'0'+base) {
n = base*n + c - '0';
s->p++;
}
if(*s->p++!=']') goto error;
if(n==0) n = 1000;
s->rep = n;
return(a);
default:
error:
write(2,"Bad string\n",11);
exit(1);
}
}
return(nextc(s));
}
nextc(s)
struct string *s;
{
register c, i, n;
c = *s->p++;
if(c=='\\') {
i = n = 0;
while(i<3 && (c = *s->p)>='0' && c<='7') {
n = n*8 + c - '0';
i++;
s->p++;
}
if(i>0) c = n;
else c = *s->p++;
}
if(c==0) *--s->p = 0;
return(c&0377);
}

48
5include/Makefile Normal file
View File

@@ -0,0 +1,48 @@
#
# @(#)Makefile 1.1 92/07/30 SMI; from UCB 4.3 83/07/10
#
# Doing a make install builds /usr/5include
#
# The ``rm -rf''s used below are safe because rm doesn't
# follow symbolic links.
#
DESTDIR=
SUBDIRS=sys
STD= assert.h \
ctype.h \
grp.h \
malloc.h \
pwd.h \
stdio.h \
stdlib.h \
time.h
LINKS= fcntl.h
CHOWN= /etc/chown
all: $(SUBDIRS) ${STD} $(LINKS)
$(SUBDIRS): FRC
@set -x;for i in $(SUBDIRS); do ( cd $$i; $(MAKE) ); done
$(LINKS): $(SUBDIRS)
rm -f $@;
ln -s sys/$@ $@
FRC:
install: all
install -d -o bin -m 755 ${DESTDIR}/usr/5include
install -d -o bin -m 755 ${DESTDIR}/usr/5include/sys
@set -x;(cd sys; for j in *.h; do \
install -c -m 444 $$j ${DESTDIR}/usr/5include/sys/$$j; \
done)
-for i in ${STD}; do \
install -c -m 444 $$i ${DESTDIR}/usr/5include/$$i; \
done
(cd ../usr.lib/libcurses; ${MAKE} DESTDIR=${DESTDIR} install_h)
-for i in ${LINKS}; do \
rm -f ${DESTDIR}/usr/5include/$$i; \
ln -s sys/$$i ${DESTDIR}/usr/5include/$$i; \
done
clean:

13
5include/assert.h Normal file
View File

@@ -0,0 +1,13 @@
/* @(#)assert.h 1.1 92/07/30 SMI; from S5R2 1.4 */
#ifndef _assert_h
#define _assert_h
#ifdef NDEBUG
#define assert(EX)
#else
extern void _assert();
#define assert(EX) if (EX) ; else _assert("EX", __FILE__, __LINE__)
#endif
#endif /*!_assert_h*/

74
5include/ctype.h Normal file
View File

@@ -0,0 +1,74 @@
/* @(#)ctype.h 1.1 92/07/30 SMI; from S5R3.1 1.9 */
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* Portions Copyright (c) 1989 Sun Microsystems, Inc. */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef __ctype_h
#define __ctype_h
#define _U 01 /* Upper case */
#define _L 02 /* Lower case */
#define _N 04 /* Numeral (digit) */
#define _S 010 /* Spacing character */
#define _P 020 /* Punctuation */
#define _C 040 /* Control character */
#define _X 0100 /* heXadecimal digit */
#define _B 0200 /* Blank */
extern int isalnum(/* int c */);
extern int isalpha(/* int c */);
#ifndef _POSIX_SOURCE
extern int isascii(/* int c */);
#endif
extern int iscntrl(/* int c */);
extern int isdigit(/* int c */);
extern int isgraph(/* int c */);
extern int islower(/* int c */);
extern int isprint(/* int c */);
extern int ispunct(/* int c */);
extern int isspace(/* int c */);
extern int isupper(/* int c */);
extern int isxdigit(/* int c */);
#ifndef _POSIX_SOURCE
extern int toascii(/* int c */);
#endif
extern int tolower(/* int c */);
extern int toupper(/* int c */);
#ifndef lint
#define isalnum(c) ((_ctype_ + 1)[c] & (_U | _L | _N))
#define isalpha(c) ((_ctype_ + 1)[c] & (_U | _L))
#ifndef _POSIX_SOURCE
#define isascii(c) (!((c) & ~0177))
#endif
#define iscntrl(c) ((_ctype_ + 1)[c] & _C)
#define isdigit(c) ((_ctype_ + 1)[c] & _N)
#define isgraph(c) ((_ctype_ + 1)[c] & (_P | _U | _L | _N))
#define islower(c) ((_ctype_ + 1)[c] & _L)
#define isprint(c) ((_ctype_ + 1)[c] & (_P | _U | _L | _N | _B))
#define ispunct(c) ((_ctype_ + 1)[c] & _P)
#define isspace(c) ((_ctype_ + 1)[c] & _S)
#define isupper(c) ((_ctype_ + 1)[c] & _U)
#define isxdigit(c) ((_ctype_ + 1)[c] & _X)
#ifndef _POSIX_SOURCE
#define toascii(c) ((c) & 0177)
/*
* These upper/lower macros are not codeset independent
*/
#define _toupper(c) ((c) - 'a' + 'A')
#define _tolower(c) ((c) - 'A' + 'a')
#endif
extern char _ctype_[];
#endif /* lint */
#endif /* !__ctype_h */

36
5include/grp.h Normal file
View File

@@ -0,0 +1,36 @@
/* @(#)grp.h 1.1 92/07/30 SMI */
#ifndef __grp_h
#define __grp_h
#include <sys/types.h>
/*
* We have to make this POSIX.1 compatible header compatible with SunOS
* Release 4.0.x and the BSD interface provided by /usr/include/grp.h
* so we have a filler to make the gid_t gr_gid field here match the
* int gr_gid field there.
* This will all go away in a later release when gid_t is enlarged.
* Until then watch out for big- vs. little-endian problems in the filler.
*/
struct group { /* see getgrent(3) */
char *gr_name;
char *gr_passwd;
#if defined(mc68000) || defined(sparc)
short gr_gid_filler;
#endif
gid_t gr_gid;
#if defined(i386)
short gr_gid_filler;
#endif
char **gr_mem;
};
#ifndef _POSIX_SOURCE
struct group *getgrent();
#endif
struct group *getgrgid(/* gid_t gid */);
struct group *getgrnam(/* char *name */);
#endif /* !__grp_h */

47
5include/malloc.h Normal file
View File

@@ -0,0 +1,47 @@
/* @(#)malloc.h 1.1 92/07/30 SMI; from include/malloc.h 1.5 */
#ifndef __malloc_h
#define __malloc_h
/*
* Constants defining mallopt operations
*/
#define M_MXFAST 1 /* set size of 'small blocks' */
#define M_NLBLKS 2 /* set num of small blocks in holding block */
#define M_GRAIN 3 /* set rounding factor for small blocks */
#define M_KEEP 4 /* (nop) retain contents of freed blocks */
/*
* malloc information structure
*/
struct mallinfo {
int arena; /* total space in arena */
int ordblks; /* number of ordinary blocks */
int smblks; /* number of small blocks */
int hblks; /* number of holding blocks */
int hblkhd; /* space in holding block headers */
int usmblks; /* space in small blocks in use */
int fsmblks; /* space in free small blocks */
int uordblks; /* space in ordinary blocks in use */
int fordblks; /* space in free ordinary blocks */
int keepcost; /* cost of enabling keep option */
int mxfast; /* max size of small blocks */
int nlblks; /* number of small blocks in a holding block */
int grain; /* small block rounding factor */
int uordbytes; /* space (including overhead) allocated in ord. blks */
int allocated; /* number of ordinary blocks allocated */
int treeoverhead; /* bytes used in maintaining the free tree */
};
typedef void * malloc_t;
extern malloc_t calloc(/* size_t nmemb, size_t size */);
extern void free(/* malloc_t ptr */);
extern malloc_t malloc(/* size_t size */);
extern malloc_t realloc(/* malloc_t ptr, size_t size */);
extern int mallopt();
extern struct mallinfo mallinfo();
#endif /* !__malloc_h */

57
5include/pwd.h Normal file
View File

@@ -0,0 +1,57 @@
/* @(#)pwd.h 1.1 92/07/30 SMI; from S5R2 1.1 */
#ifndef __pwd_h
#define __pwd_h
#include <sys/types.h>
/*
* We have to make this POSIX.1 compatible header compatible with SunOS
* Release 4.0.x and the BSD interface provided by /usr/include/pwd.h
* so we have fillers to make the gid_t pw_gid field here match the
* int pw_gid field there and the uid_t pw_uid field here match the
* int pw_uid field there.
* This will all go away in a later release when gid_t is enlarged.
* Until then watch out for big- vs. little-endian problems in the filler.
*/
struct passwd {
char *pw_name;
char *pw_passwd;
#if defined(mc68000) || defined(sparc)
short pw_uid_filler;
#endif
uid_t pw_uid;
#if defined(i386)
short pw_uid_filler;
#endif
#if defined(mc68000) || defined(sparc)
short pw_gid_filler;
#endif
gid_t pw_gid;
#if defined(i386)
short pw_gid_filler;
#endif
char *pw_age;
char *pw_comment;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
#ifndef _POSIX_SOURCE
extern struct passwd *getpwent();
struct comment {
char *c_dept;
char *c_name;
char *c_acct;
char *c_bin;
};
#endif
struct passwd *getpwuid(/* uid_t uid */);
struct passwd *getpwnam(/* char *name */);
#endif /* !__pwd_h */

181
5include/stdio.h Normal file
View File

@@ -0,0 +1,181 @@
/* @(#)stdio.h 1.1 92/07/30 SMI; from S5R2 2.7 */
#ifdef comment /* ======================================================= */
"Standard" header file definition. See the C style paper for
full explanations. Note that this reorganization has been
forced upon us by ANSI C; please abide by it. This file, aside
from this comment, is supposed to be a good example.
/* sccs id stuff */
#ifndef __[dir_]_filename_h
#define __[dir_]_filename_h
#include /* all includes come first */
#define /* all defines other than function like macros */
structs
unions
enums
function prototypes
/*
* macros that are supplied as C functions have to be defined after
* the C prototype.
*/
#define /* all function like macros */
extern variables
#endif __[dir_]_filename_h
#endif /* comment ======================================================= */
#ifndef __stdio_h
#define __stdio_h
#include <sys/stdtypes.h> /* for size_t */
#if pdp11
#define BUFSIZ 512
#elif u370
#define BUFSIZ 4096
#else /* just about every other UNIX system in existence */
#define BUFSIZ 1024
#endif
#ifndef EOF
#define EOF (-1)
#endif
#define L_ctermid 9
#define L_cuserid 9
#define L_tmpnam 25 /* (sizeof (_tmpdir) + 15) */
#define _tmpdir "/usr/tmp/"
#define FILENAME_MAX 1025
#define TMP_MAX 17576
/*
* ANSI C requires definitions of SEEK_CUR, SEEK_END, and SEEK_SET here.
* They must be kept in sync with SEEK_* in <sys/unistd.h> (as required
* by POSIX.1) and L_* in <sys/file.h>.
* FOPEN_MAX should follow definition of _POSIX_OPEN_MAX in <sys/unistd.h>.
*/
#ifndef SEEK_SET
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#endif
#define FOPEN_MAX 16
#ifndef _POSIX_SOURCE
#define P_tmpdir _tmpdir
#endif
#ifndef NULL
#define NULL 0
#endif
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
/*
* _IOLBF means that a file's output will be buffered line by line
* In addition to being flags, _IONBF, _IOLBF and _IOFBF are possible
* values for "type" in setvbuf.
*/
#define _IOFBF 0000
#define _IOREAD 0001
#define _IOWRT 0002
#define _IONBF 0004
#define _IOMYBUF 0010
#define _IOEOF 0020
#define _IOERR 0040
#define _IOSTRG 0100
#define _IOLBF 0200
#define _IORW 0400
/*
* buffer size for multi-character output to unbuffered files
*/
#define _SBFSIZ 8
typedef struct {
#if pdp11 || u370
unsigned char *_ptr;
int _cnt;
#else /* just about every other UNIX system in existence */
int _cnt;
unsigned char *_ptr;
#endif
unsigned char *_base;
int _bufsiz;
short _flag;
unsigned char _file; /* should be short */
} FILE;
#ifndef _POSIX_SOURCE
extern char *ctermid(/* char *s */); /* unistd.h */
extern char *cuserid(/* char *s */); /* unistd.h */
extern FILE *popen(/* char *prog, char *mode */);
extern char *tempnam(/* char *d, char *s */);
#endif
extern void clearerr(/* FILE *stream */);
extern int fclose(/* FILE *f */);
extern FILE *fdopen(/* int fd, char *type */);
extern int feof(/* FILE *f */);
extern int ferror(/* FILE *f */);
extern int fflush(/* FILE *f */);
extern int fgetc(/* FILE *f */);
extern int fileno(/* FILE *f */);
extern FILE *fopen(/* const char *path, const char *mode */);
extern char *fgets(/* char *s, int n, FILE *f */);
extern int fprintf(/* FILE *f, const char *fmt, ... */);
extern int fputc(/* int c, FILE *f */);
extern int fputs(/* const char *s, FILE *f */);
extern size_t fread(/* void *ptr, size_t size, size_t nmemb, FILE *f */);
extern FILE *freopen(/* const char *filename, const char *mode, FILE *f */);
extern int fscanf(/* FILE *f, const char *format, ... */);
extern int fseek(/* FILE *f, long int offset, int whence */);
extern long ftell(/* FILE *f */);
extern size_t fwrite(/* const void *p, size_t size, size_t nmemb, FILE *f */);
extern int getc(/* FILE *f */);
extern int getchar(/* void */);
extern char *gets(/* char *s */);
extern void perror(/* const char *s */);
extern int printf(/* const char *fmt, ... */);
extern int putc(/* int c, FILE *f */);
extern int putchar(/* int c */);
extern int puts(/* const char *s */);
extern int remove(/* const char *filename */);
extern int rename(/* char *old, char *new */);
extern void rewind(/* FILE *f */);
extern int scanf(/* const char *format, ... */);
extern void setbuf(/* FILE *f, char *b */);
extern int sprintf(/* char *s, const char *fmt, ... */);
extern int sscanf(/* const char *s, const char *format, ... */);
extern FILE *tmpfile(/* void */);
extern char *tmpnam(/* char *s */);
extern int ungetc(/* int c, FILE *f */);
#ifndef lint
#define getc(p) (--(p)->_cnt >= 0 ? ((int) *(p)->_ptr++) : _filbuf(p))
#define putc(x, p) (--(p)->_cnt >= 0 ?\
(int)(*(p)->_ptr++ = (unsigned char)(x)) :\
(((p)->_flag & _IOLBF) && -(p)->_cnt < (p)->_bufsiz ?\
((*(p)->_ptr = (unsigned char)(x)) != '\n' ?\
(int)(*(p)->_ptr++) :\
_flsbuf(*(unsigned char *)(p)->_ptr, p)) :\
_flsbuf((unsigned char)(x), p)))
#define getchar() getc(stdin)
#define putchar(x) putc((x), stdout)
#define clearerr(p) ((void) ((p)->_flag &= ~(_IOERR | _IOEOF)))
#define feof(p) (((p)->_flag & _IOEOF) != 0)
#define ferror(p) (((p)->_flag & _IOERR) != 0)
#define fileno(p) (p)->_file
#endif
extern FILE _iob[];
#endif /* !__stdio_h */

49
5include/stdlib.h Normal file
View File

@@ -0,0 +1,49 @@
/* @(#)stdlib.h 1.1 92/07/30 SMI */
/*
* stdlib.h
*/
#ifndef __stdlib_h
#define __stdlib_h
#include <sys/stdtypes.h> /* to get size_t */
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#define RAND_MAX 0x7fff
#ifndef NULL
#define NULL 0
#endif
extern unsigned int _mb_cur_max;
#define MB_CUR_MAX _mb_cur_max
/* declaration of various libc functions */
extern void abort(/* void */);
extern int abs(/* int j */);
extern double atof(/* const char *nptr */);
extern int atoi(/* const char *nptr */);
extern long int atol(/* const char *nptr */);
extern void * bsearch(/* const void *key, const void *base, size_t nmemb,
size_t size, int (*compar)(const void *, const void *) */);
extern void * calloc(/* size_t nmemb, size_t size */);
extern void exit(/* int status */);
extern void free(/* void *ptr */);
extern char * getenv(/* const char *name */);
extern void * malloc(/* size_t size */);
extern void qsort(/* void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *) */);
extern int rand(/* void */);
extern void * realloc(/* void *ptr, size_t size */);
extern void srand(/* unsigned int seed */);
extern int mbtowc(/* wchar_t *pwc, const char *s, size_t n */);
extern int wctomb(/* char *s, wchar_t wchar */);
extern size_t mbstowcs(/* wchar_t *pwcs, const char *s, size_t n */);
extern size_t wcstombs(/* char *s, const wchar_t *pwcs, size_t n */);
#define mblen(s, n) mbtowc((wchar_t *)0, s, n)
#endif

10
5include/sys/Makefile Normal file
View File

@@ -0,0 +1,10 @@
# @(#)Makefile 1.1 92/07/30 SMI
#
H = fcntl.h
all: $H
clean:
# Install is done by parent makefile
install:

12
5include/sys/fcntl.h Normal file
View File

@@ -0,0 +1,12 @@
/* @(#)fcntl.h 1.1 92/07/30 SMI */
#ifndef __sys_fcntl_h
#define __sys_fcntl_h
#include <sys/fcntlcom.h>
#ifndef _POSIX_SOURCE
#define O_NDELAY _FNBIO /* Non-blocking I/O (S5 style) */
#endif
#endif /* !__sys_fcntl_h */

58
5include/time.h Normal file
View File

@@ -0,0 +1,58 @@
/* @(#)time.h 1.1 92/07/30 SMI; from S5R2 1.1 */
#ifndef __time_h
#define __time_h
#include <sys/stdtypes.h>
#ifndef NULL
#define NULL 0
#endif
struct tm { /* see ctime(3) */
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
char *tm_zone;
long tm_gmtoff;
};
/*
* Following 2 lines are required to make CLK_TCK work.
* If they change here they have to change in <sys/unistd.h> as well.
*/
extern long sysconf(/* int name */);
#define _SC_CLK_TCK 3 /* clock ticks/sec */
/*
* POSIX.1 uses CLK_TCK to specify units used by times(3).
* POSIX.1a doesn't use a name for this and says CLK_TCK is obsolescent, but
* we'll probably have to support it for a long time.
*/
#define CLK_TCK (sysconf(_SC_CLK_TCK))
/* 881207 ANSI C draft uses CLOCKS_PER_SEC to specify units used by clock(3). */
#define CLOCKS_PER_SEC 1000000L
extern char * asctime(/* const struct tm *t */);
extern char * ctime(/* const time_t *t */);
extern struct tm * gmtime(/* const time_t *t */);
extern struct tm * localtime(/* const time_t *t */);
extern time_t mktime(/* struct tm *timeptr */);
extern size_t strftime(/* char *s, size_t maxsize, const char *format,
const struct tm *timeptr */);
extern time_t time(/* time_t *t */);
extern void tzset(/* void */);
extern char *tzname[];
#ifndef _POSIX_SOURCE
extern int daylight;
extern long timezone;
extern void tzsetwall(/* void */);
#endif !_POSIX_SOURCE
#endif !__time_h

69
5lib/Makefile Normal file
View File

@@ -0,0 +1,69 @@
#
# @(#)Makefile 1.1 92/07/30 SMI
#
DESTDIR=
CFLAGS= -O
# Programs that live in subdirectories, and have makefiles of their own.
#
SUBDIR= compile libcurses liby terminfo
# Shell scripts that need only be installed and are never removed.
#
SCRIPT=
# C programs that live in the current directory and do not need
# explicit make lines.
#
STD=
# C programs that live in the current directory and need explicit make lines.
#
NSTD=
all: ${SUBDIR} ${STD} ${NSTD}
${SUBDIR}: FRC
cd $@; make ${MFLAGS}
#${STD}:
# cc ${CFLAGS} -o $@ $@.c
install: ${STD} ${NSTD}
-mkdir ${DESTDIR}/usr/5lib && chown bin ${DESTDIR}/usr/5lib && \
chmod 755 ${DESTDIR}/usr/5lib
for i in ${SUBDIR}; do \
(cd $$i; make ${MFLAGS} DESTDIR=${DESTDIR} install); done
# for i in ${SCRIPT}; do (install -c $$i.sh ${DESTDIR}/usr/5lib/$$i); done
# for i in ${STD} ${NSTD}; do (install -s $$i ${DESTDIR}/usr/5lib/$$i); done
clean:
rm -f a.out core *.s *.o
for i in ${SUBDIR}; do (cd $$i; make ${MFLAGS} clean); done
rm -f ${STD} ${NSTD}
depend:
cat </dev/null >x.c
for i in ${STD} ${NSTD}; do \
(echo $$i: $$i.c >>makedep; \
/bin/grep '^#[ ]*include' x.c $$i.c | sed \
-e '/\.\.\/h/d' \
-e 's,<\(.*\)>,"/usr/include/\1",' \
-e 's/:[^"]*"\([^"]*\)".*/: \1/' \
-e 's/\.c//' >>makedep); done
echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
echo '$$r makedep' >>eddep
echo 'w' >>eddep
cp Makefile Makefile.bak
ed - Makefile < eddep
rm eddep makedep x.c
echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
echo '# see make depend above' >> Makefile
FRC:
# Files listed in ${NSTD} have explicit make lines given below.
# DO NOT DELETE THIS LINE -- make depend uses it

399
5lib/compile/Makefile Normal file
View File

@@ -0,0 +1,399 @@
#
# @(#)Makefile 1.1 92/07/30 SMI
#
#
# Makefile for /lib/compile (driver for cc, f77, pc, m2c, lint, ...)
#
# -----------------------------------------------------------------------------
# RELEASE=32 for Release 3.x version.
# RELEASE=40 for Release 4.x version.
RELEASE = 40
# SRCDIR=. for regular version.
# SRCDIR=../../lang/compile for Sys-V 3.x,4.0 version.
# SRCDIR=../../lang/compile for 4BSD 4.1 version.
SRCDIR = ../../lang/compile
# S5EMUL= for regular 3.x, 4.0 version.
# S5EMUL=-DS5EMUL for Sys-V 3.x, 4.0 version.
# S5EMUL=-DS5EMUL for regular 4.1 version.
# S5EMUL= for 4BSD 4.1 version.
S5EMUL =
# VROOT=../vroot for regular version.
# VROOT=../../lang/vroot for Sys-V 3.x,4.0 version.
# VROOT=../../lang/vroot for 4BSD 4.1 version.
VROOT = ../../lang/vroot
# LIB=/lib for regular 3.x version
# LIB=/usr/5lib for Sys-V 3.x version
# LIB=/usr/lib for regular 4.0 version
# LIB=/usr/5lib for Sys-V 4.0 version
# LIB=/usr/lib for regular 4.1 version
# LIB=/usr/ucblib for 4BSD 4.1 version
LIB = /usr/ucblib
# -----------------------------------------------------------------------------
ARCH = /bin/arch
CPP = /lib/cpp
LINT = /usr/bin/lint
# HANDLE_R32 is for making a version which will understand
# R3.2 directory structure as well as R4.0 directory structure.
# This is needed for cross-compilation.
xCPPFLAGS = -D`$(ARCH)` -I$(SRCDIR) -I$(VROOT) -DRELEASE=$(RELEASE) -DHANDLE_R32 $(S5EMUL)
COPTS = -O
CFLAGS = $(COPTS) $(xCPPFLAGS)
LDFLAGS =
LIBS =
LINTFLAGS = -x $(xCPPFLAGS)
INSTALL = install
XLINKS = xcc xm2c xf77 xpc xlint
#
# Driver sources and headers.
#
ROCSRCS = $(SRCDIR)/ro_data.c
CSRCS = $(SRCDIR)/compile.c $(SRCDIR)/driver_version.c \
$(SRCDIR)/rw_data.c $(SRCDIR)/ro_data.c \
$(SRCDIR)/run_pass.c $(SRCDIR)/setup.c $(SRCDIR)/setup_cc.c \
$(SRCDIR)/setup_f77.c $(SRCDIR)/setup_lint.c \
$(SRCDIR)/setup_m2c.c $(SRCDIR)/setup_pc.c
HDRS = $(SRCDIR)/driver.h $(VROOT)/report.h $(VROOT)/vroot.h
SRCS = $(ROSRCS) $(CSRCS) $(HDRS)
#
# Driver objects.
#
LINTS = compile.ln driver_version.ln rw_data.ln ro_data.ln run_pass.ln \
setup.ln setup_cc.ln \
setup_f77.ln setup_lint.ln setup_m2c.ln setup_pc.ln
ROOBJS = ro_data.o
COBJS = compile.o driver_version.o rw_data.o run_pass.o setup.o setup_cc.o \
setup_f77.o setup_lint.o setup_m2c.o setup_pc.o
OBJS = $(ROOBJS) $(COBJS)
#
# Production rules for driver.
#
compile: $(OBJS) $(VROOT)/vroot.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(VROOT)/vroot.a
$(XLINKS):
rm -f $@; ln -s compile $@
xlinks: $(XLINKS)
$(COBJS): $(HDRS)
$(CC) $(CFLAGS) -c -o $(@F) $(SRCDIR)/`basename $(@F) .o`.c
$(VROOT)/vroot.a $(VROOT)/report.h $(VROOT)/vroot.h:
cd $(@D); $(MAKE) $(@F)
FRC:
.c.ln:
$(LINT) $(LINTFLAGS) -i $*.c
# read-only (sharable) data
ro_data.o: $(SRCDIR)/ro_data.c
$(CC) $(CFLAGS) -c $(SRCDIR)/ro_data.c -R
lint: $(LINTS)
lint $(LINTS) $(LINTFLAGS)
install: compile
$(INSTALL) -s compile $(DESTDIR)$(LIB)/compile
tags: $(SRCS)
ctags $(SRCS)
testdir:
TEST=dtest.`arch`; \
if [ ! -d $${TEST} ] ; \
then \
set -x; \
mkdir $${TEST} ; \
ln -s ../SCCS/../$${TEST}/SCCS SCCS; \
(cd $${TEST}; /usr/ucb/sccs get SCCS) ; \
fi ; \
for CMD in cc f77 pc m2c lint; \
do \
( cd $${TEST}; \
if [ ! -f $${CMD} ] ; then ln -s ../compile $${CMD}; fi ; \
) ; \
done
buildtest: dtest compile testdir
TEST=dtest.`arch`; \
for CMD in cc f77 pc m2c lint; \
do \
( cd $${TEST}; \
for FILE in $${CMD}*.dtest ; \
do \
chmod u+w $${FILE} ; \
../dtest -b $${FILE} ; \
chmod a-w $${FILE} ; \
done ; \
) ; \
done
test: dtest compile testdir
TEST=dtest.`arch`; \
for CMD in cc f77 pc m2c lint; \
do \
( cd $${TEST}; \
for FILE in $${CMD}*.dtest ; \
do \
chmod u+w $${FILE} ; \
../dtest $${FILE} ; \
chmod a-w $${FILE} ; \
done ; \
) ; \
done
#
# Miscellaneous production rules.
#
clean:
rm -f $(OBJS) compile ocompile $(LINTS) *.BAK tags
rm -f gen gen.o syscall.a
rm -f $(XLINKS)
depend: $(SRCS)
rm -f makedep
for i in $(CSRCS); do \
( $(CPP) -M $(xCPPFLAGS) $$i >> makedep ); \
done
echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
echo '$$r makedep' >>eddep
echo 'w' >>eddep
cp Makefile Makefile.bak
ed - Makefile < eddep
echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
echo '# see make depend above' >> Makefile
rm -f eddep makedep
# DO NOT DELETE THIS LINE -- make depend uses it
compile.o: ../../lang/compile/compile.c
compile.o: ../../lang/compile/driver.h
compile.o: /usr/include/stdio.h
compile.o: /usr/include/sys/types.h
compile.o: /usr/include/sys/sysmacros.h
compile.o: /usr/include/sys/time.h
compile.o: /usr/include/time.h
compile.o: /usr/include/sys/resource.h
compile.o: /usr/include/sys/param.h
compile.o: /usr/include/machine/param.h
compile.o: /usr/include/sys/signal.h
compile.o: /usr/include/vm/faultcode.h
compile.o: /usr/include/sys/types.h
compile.o: ../../lang/vroot/report.h
compile.o: /usr/include/stdio.h
compile.o: ../../lang/vroot/vroot.h
compile.o: /usr/include/stdio.h
compile.o: /usr/include/alloca.h
compile.o: /usr/include/signal.h
compile.o: /usr/include/sys/types.h
compile.o: /usr/include/sys/stat.h
compile.o: /usr/include/alloca.h
driver_version.o: ../../lang/compile/driver_version.c
driver_version.o: /usr/include/stdio.h
driver_version.o: /usr/include/sys/file.h
driver_version.o: /usr/include/sys/fcntlcom.h
driver_version.o: ../../lang/compile/driver.h
driver_version.o: /usr/include/stdio.h
driver_version.o: /usr/include/sys/types.h
driver_version.o: /usr/include/sys/sysmacros.h
driver_version.o: /usr/include/sys/time.h
driver_version.o: /usr/include/time.h
driver_version.o: /usr/include/sys/resource.h
driver_version.o: /usr/include/sys/param.h
driver_version.o: /usr/include/machine/param.h
driver_version.o: /usr/include/sys/signal.h
driver_version.o: /usr/include/vm/faultcode.h
driver_version.o: /usr/include/sys/types.h
driver_version.o: ../../lang/vroot/report.h
driver_version.o: /usr/include/stdio.h
driver_version.o: ../../lang/vroot/vroot.h
driver_version.o: /usr/include/stdio.h
driver_version.o: /usr/include/alloca.h
rw_data.o: ../../lang/compile/rw_data.c
rw_data.o: ../../lang/compile/driver.h
rw_data.o: /usr/include/stdio.h
rw_data.o: /usr/include/sys/types.h
rw_data.o: /usr/include/sys/sysmacros.h
rw_data.o: /usr/include/sys/time.h
rw_data.o: /usr/include/time.h
rw_data.o: /usr/include/sys/resource.h
rw_data.o: /usr/include/sys/param.h
rw_data.o: /usr/include/machine/param.h
rw_data.o: /usr/include/sys/signal.h
rw_data.o: /usr/include/vm/faultcode.h
rw_data.o: /usr/include/sys/types.h
rw_data.o: ../../lang/vroot/report.h
rw_data.o: /usr/include/stdio.h
rw_data.o: ../../lang/vroot/vroot.h
rw_data.o: /usr/include/stdio.h
rw_data.o: /usr/include/alloca.h
ro_data.o: ../../lang/compile/ro_data.c
ro_data.o: ../../lang/compile/driver.h
ro_data.o: /usr/include/stdio.h
ro_data.o: /usr/include/sys/types.h
ro_data.o: /usr/include/sys/sysmacros.h
ro_data.o: /usr/include/sys/time.h
ro_data.o: /usr/include/time.h
ro_data.o: /usr/include/sys/resource.h
ro_data.o: /usr/include/sys/param.h
ro_data.o: /usr/include/machine/param.h
ro_data.o: /usr/include/sys/signal.h
ro_data.o: /usr/include/vm/faultcode.h
ro_data.o: /usr/include/sys/types.h
ro_data.o: ../../lang/vroot/report.h
ro_data.o: /usr/include/stdio.h
ro_data.o: ../../lang/vroot/vroot.h
ro_data.o: /usr/include/stdio.h
ro_data.o: /usr/include/alloca.h
run_pass.o: ../../lang/compile/run_pass.c
run_pass.o: ../../lang/compile/driver.h
run_pass.o: /usr/include/stdio.h
run_pass.o: /usr/include/sys/types.h
run_pass.o: /usr/include/sys/sysmacros.h
run_pass.o: /usr/include/sys/time.h
run_pass.o: /usr/include/time.h
run_pass.o: /usr/include/sys/resource.h
run_pass.o: /usr/include/sys/param.h
run_pass.o: /usr/include/machine/param.h
run_pass.o: /usr/include/sys/signal.h
run_pass.o: /usr/include/vm/faultcode.h
run_pass.o: /usr/include/sys/types.h
run_pass.o: ../../lang/vroot/report.h
run_pass.o: /usr/include/stdio.h
run_pass.o: ../../lang/vroot/vroot.h
run_pass.o: /usr/include/stdio.h
run_pass.o: /usr/include/alloca.h
run_pass.o: /usr/include/sys/wait.h
run_pass.o: /usr/include/sys/file.h
run_pass.o: /usr/include/sys/fcntlcom.h
run_pass.o: /usr/include/ctype.h
setup.o: ../../lang/compile/setup.c
setup.o: ../../lang/compile/driver.h
setup.o: /usr/include/stdio.h
setup.o: /usr/include/sys/types.h
setup.o: /usr/include/sys/sysmacros.h
setup.o: /usr/include/sys/time.h
setup.o: /usr/include/time.h
setup.o: /usr/include/sys/resource.h
setup.o: /usr/include/sys/param.h
setup.o: /usr/include/machine/param.h
setup.o: /usr/include/sys/signal.h
setup.o: /usr/include/vm/faultcode.h
setup.o: /usr/include/sys/types.h
setup.o: ../../lang/vroot/report.h
setup.o: /usr/include/stdio.h
setup.o: ../../lang/vroot/vroot.h
setup.o: /usr/include/stdio.h
setup.o: /usr/include/alloca.h
setup_cc.o: ../../lang/compile/setup_cc.c
setup_cc.o: ../../lang/compile/driver.h
setup_cc.o: /usr/include/stdio.h
setup_cc.o: /usr/include/sys/types.h
setup_cc.o: /usr/include/sys/sysmacros.h
setup_cc.o: /usr/include/sys/time.h
setup_cc.o: /usr/include/time.h
setup_cc.o: /usr/include/sys/resource.h
setup_cc.o: /usr/include/sys/param.h
setup_cc.o: /usr/include/machine/param.h
setup_cc.o: /usr/include/sys/signal.h
setup_cc.o: /usr/include/vm/faultcode.h
setup_cc.o: /usr/include/sys/types.h
setup_cc.o: ../../lang/vroot/report.h
setup_cc.o: /usr/include/stdio.h
setup_cc.o: ../../lang/vroot/vroot.h
setup_cc.o: /usr/include/stdio.h
setup_cc.o: /usr/include/alloca.h
setup_f77.o: ../../lang/compile/setup_f77.c
setup_f77.o: ../../lang/compile/driver.h
setup_f77.o: /usr/include/stdio.h
setup_f77.o: /usr/include/sys/types.h
setup_f77.o: /usr/include/sys/sysmacros.h
setup_f77.o: /usr/include/sys/time.h
setup_f77.o: /usr/include/time.h
setup_f77.o: /usr/include/sys/resource.h
setup_f77.o: /usr/include/sys/param.h
setup_f77.o: /usr/include/machine/param.h
setup_f77.o: /usr/include/sys/signal.h
setup_f77.o: /usr/include/vm/faultcode.h
setup_f77.o: /usr/include/sys/types.h
setup_f77.o: ../../lang/vroot/report.h
setup_f77.o: /usr/include/stdio.h
setup_f77.o: ../../lang/vroot/vroot.h
setup_f77.o: /usr/include/stdio.h
setup_f77.o: /usr/include/alloca.h
setup_lint.o: ../../lang/compile/setup_lint.c
setup_lint.o: ../../lang/compile/driver.h
setup_lint.o: /usr/include/stdio.h
setup_lint.o: /usr/include/sys/types.h
setup_lint.o: /usr/include/sys/sysmacros.h
setup_lint.o: /usr/include/sys/time.h
setup_lint.o: /usr/include/time.h
setup_lint.o: /usr/include/sys/resource.h
setup_lint.o: /usr/include/sys/param.h
setup_lint.o: /usr/include/machine/param.h
setup_lint.o: /usr/include/sys/signal.h
setup_lint.o: /usr/include/vm/faultcode.h
setup_lint.o: /usr/include/sys/types.h
setup_lint.o: ../../lang/vroot/report.h
setup_lint.o: /usr/include/stdio.h
setup_lint.o: ../../lang/vroot/vroot.h
setup_lint.o: /usr/include/stdio.h
setup_lint.o: /usr/include/alloca.h
setup_lint.o: /usr/include/sys/file.h
setup_lint.o: /usr/include/sys/fcntlcom.h
setup_m2c.o: ../../lang/compile/setup_m2c.c
setup_m2c.o: ../../lang/compile/driver.h
setup_m2c.o: /usr/include/stdio.h
setup_m2c.o: /usr/include/sys/types.h
setup_m2c.o: /usr/include/sys/sysmacros.h
setup_m2c.o: /usr/include/sys/time.h
setup_m2c.o: /usr/include/time.h
setup_m2c.o: /usr/include/sys/resource.h
setup_m2c.o: /usr/include/sys/param.h
setup_m2c.o: /usr/include/machine/param.h
setup_m2c.o: /usr/include/sys/signal.h
setup_m2c.o: /usr/include/vm/faultcode.h
setup_m2c.o: /usr/include/sys/types.h
setup_m2c.o: ../../lang/vroot/report.h
setup_m2c.o: /usr/include/stdio.h
setup_m2c.o: ../../lang/vroot/vroot.h
setup_m2c.o: /usr/include/stdio.h
setup_m2c.o: /usr/include/alloca.h
setup_pc.o: ../../lang/compile/setup_pc.c
setup_pc.o: ../../lang/compile/driver.h
setup_pc.o: /usr/include/stdio.h
setup_pc.o: /usr/include/sys/types.h
setup_pc.o: /usr/include/sys/sysmacros.h
setup_pc.o: /usr/include/sys/time.h
setup_pc.o: /usr/include/time.h
setup_pc.o: /usr/include/sys/resource.h
setup_pc.o: /usr/include/sys/param.h
setup_pc.o: /usr/include/machine/param.h
setup_pc.o: /usr/include/sys/signal.h
setup_pc.o: /usr/include/vm/faultcode.h
setup_pc.o: /usr/include/sys/types.h
setup_pc.o: ../../lang/vroot/report.h
setup_pc.o: /usr/include/stdio.h
setup_pc.o: ../../lang/vroot/vroot.h
setup_pc.o: /usr/include/stdio.h
setup_pc.o: /usr/include/alloca.h
# DEPENDENCIES MUST END AT END OF FILE
# IF YOU PUT STUFF HERE IT WILL GO AWAY
# see make depend above

41
Copyright Normal file
View File

@@ -0,0 +1,41 @@
SunOS 4.1.3 SUNSRC
CDROM (UFS format), 1 of 1
Part Number: 704-3207-10
(C) 1983-1992 Sun Microsystems, Inc. Printed in the United States of America. 2550 Garcia Avenue, Mountain View, California, 94043-1100 U.S.A.
All rights reserved. This product or document is protected by copyright and
distributed under licenses restricting its use, copying, distribution and
decompilation. No part of this product or document may be reproduced in any
form by any means without prior written authorization of Sun and its licensors,
if any.
Portions of this product may be derived from the UNIX(R) and Berkeley 4.3 BSD
systems, licensed from UNIX Systems Laboratories, Inc. and the University of
California, respectively. Third party font software in this product is
protected by copyright and licensed from Sun's Font Suppliers.
RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the government is
subject to restrictions as set forth in subparagraph (c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS 252.227-7013 and
FAR 52.227-19.
Sun, Sun Microsystems, the Sun Logo, SunOS, OpenWindows and Solaris
are trademarks or registered trademarks of Sun Microsystems, Inc. UNIX and
OPEN LOOK are registered trademarks of UNIX System Laboratories, Inc. All
other product names mentioned herein are the trademarks of their respective
owners. All SPARC trademarks, including the SCD Compliant Logo, are trademarks or registered trademarks of SPARC International, Inc. SPARCstation,
SPARCserver, SPARCengine, SPARCworks, SPARCompiler, SPARCprinter and SPARCware
are licensed exclusively to Sun Microsystems, Inc. Products bearing SPARC
trademarks are based upon an architecture developed by Sun Microsystems, Inc.
The OPEN LOOK(R) and Sun(TM) Graphical User Interfaces were developed by
Sun Microsystems, Inc. for its users and licensees. Sun acknowledges the
pioneering efforts of Xerox in researching and developing the concept of
visual or graphical user interfaces for the computer industry. Sun holds
a non-exclusive license from Xerox to the Xerox Graphical User Interface,
which license also covers Sun's licensees who implement OPEN LOOK GUIs and
otherwise comply with Sun's written license agreements.
The X Window System is a product of the Massachusetts Institute of Technology.

437
Makefile Normal file
View File

@@ -0,0 +1,437 @@
#
# @(#)Makefile 1.1 92/07/30 SMI
#
DESTDIR = /proto
SH = /bin/sh
ECHO = /bin/echo
RM = /bin/rm
DATE = /bin/date
CPP = /lib/cpp
CHOWN = /etc/chown
GREP = /usr/bin/grep
LS = /bin/ls
PSTAT = /usr/etc/pstat
# kludges...
RELEASE_SRC= ./release
INSTALL_SRC= ./usr.bin
MAKE_SRC= ./bin/make
SCCS_SRC= ./sccs
CONFIG_SRC= ./usr.etc/config
MAKEINSTALL= /usr/release/bin/makeinstall
WINSTALL= /usr/release/bin/winstall
UNMOUNT = /usr/release/bin/unmount
INCDIR = /usr/tmp
CRYPT = sundist/exclude.lists/crypt.kit
.DEFAULT:
sccs get $@
#
# Programs that live in subdirectories, and have makefiles of their own.
# Order here is critical for make install.
#
# suninstall *must* come last
# the libraries *must* come first
#
LAST= usr.etc/suninstall
SUBDIR= etc bin usr.etc usr.bin ucb 5bin \
xpginclude xpglib xpgbin posixlib adm files man pub sccs \
diagnostics sys demo games old ${LAST}
#LIBDIR= include lib usr.lib 5include 5lib
LIBDIR= lib usr.lib ucblib
INCLDIR= include ucbinclude
CRYPTDIR= lib 5lib include include/rpcsvc bin etc ucb share \
share/man share/man/man1 share/man/man3
#
# Directories that must exist before make install
#
DIRS= etc tmp var var/adm var/crash var/log var/preserve var/spool var/tmp \
dev mnt usr sbin home
USRDIRS= bin ucb etc include 5bin 5lib 5include lib share hosts \
boot local old kvm xpg2include xpg2lib xpg2bin
#
# The default target populates the /usr/src tree, installs the new header
# files, builds, tests, and installs the new language tools, and finally
# compiles all of /usr/src.
#
all: INCBOOT LANGBOOT lang LIBRARIES ${SUBDIR}
@${ECHO} "Build done on" `${DATE}` > BUILT
@cat BUILT
BUILT:
${MAKE} DESTDIR=${DESTDIR} CHOWN=${CHOWN} all
#########################
#
# HOW TO DO IT:
#
# At this writing, the recommended sequence of commands to produce
# an entire release starting in a bare directory is:
#
# mkdir SCCS_DIRECTORIES
# mount `pwd`/SCCS_DIRECTORIES
# ln -s SCCS_DIRECTORIES/SCCS
# make POPULATED
# su -c "make makeinstall"
# make all
# su -c "make proto"
#########################
#
# STEP 0: RESOURCES
#
# Before going any further, check to ensure that we have the resources
# and environment we need to build the release.
#
.INIT: environment
environment:
@k=`df ${INCDIR} |sed 1d|awk ' { print $$4 }'`;\
if [ $$k -lt 4000 ] ; then \
echo ${INCDIR} "does not have enough space in it!"; \
echo "Make at least 4M available and try again."; \
false;\
elif [ `csh -c limit|grep stacksize|awk '{print $$2}'` -lt 24000 ]; \
then \
echo "Stacksize limit too low!"; \
echo "Increase stack limit to at least 24M and try again."; \
false; \
fi
#########################
#
# STEP 1: POPULATE
#
# Assume a parallel hierarchy of SCCS files rooted at ./SCCS_DIRECTORIES.
# The POPULATE pass at least creates all the subdirectories and sets up
# the SCCS links. If a file named RELEASE exists in the current directory,
# and contains a string naming an SID-list file found in ./SIDlist,
# then all the source files needed to build that release will be checked out.
#
POPULATED: populate
${MAKE} clobber
${SH} populate
${MAKE} links
${ECHO} "Source Tree populated on" `${DATE}` > $@
clobber: unpopulate
if [ -f RELEASE ]; then ${SH} unpopulate; fi
${RM} -f POPULATED
links: rmlinks
${CPP} makelinks | ${SH} -x
rmlinks: makelinks
${CPP} -DCLEAN makelinks | ${SH} -x
#########################
#
# STEP 1.5 UTIL_BOOT
#
# This step makes and installs from source all those odd ball utilities
# which, in the past, have had new features added which a current build
# would depend on. Because the new version was not installed before the
# build started, the build would come to a halt at the point where the
# new feature was needed. It is expected that this list may grow.
#
# Note: there may at some time develop a "chicken/egg" loop if any of
# these utilities themselves are changed such that they need a new or
# changed header file installed before it could correctly build (the
# new header files are installed after this step in STEP number 2).
# If this rare case arises, you will have to manually install the
# header file(s) before this step.
# Another case to consider is that of config. This program depends
# on yacc, lex, and libln. As these programs are pretty stable,
# and, as any changes to them will probably not affect config,
# it probably will not be a problem. Still, they must be considered
# in the worst case.
UTIL_BOOT: POPULATED
@$(MAKE) unmount
cd ${INSTALL_SRC}; make installcmd; \
${WINSTALL} installcmd /usr/bin/install;
cd ${MAKE_SRC}; ${MAKEINSTALL} DESTDIR=
cd ${SCCS_SRC}; ${MAKEINSTALL} DESTDIR=
cd ${CONFIG_SRC}; ${MAKEINSTALL} DESTDIR=
@${ECHO} "Made UTIL_BOOT on" `${DATE}` > $@
#
# Since UTIL_BOOT is the first target after the populate pass, it's here
# that we do the rest of the environmental setup. (We couldn't do it
# sooner, or the populate pass would have clobbered anything we did.)
#
# We check to see if we're building an SID-based
# release. If so, then we need to unmount the SCCS directories
# before we actually start to build anything.
#
unmount: $(MAKEINSTALL)
@set -x; if [ -f RELEASE -a -d SCCS_DIRECTORIES/SCCS ]; then \
${UNMOUNT} `pwd`/SCCS_DIRECTORIES; \
fi
#
# Unfortunately, some parts of the build must be done as root.
# makeinstall and unmount are setuid-root scripts which are built
# and installed while running as root.
#
makeinstall: $(MAKEINSTALL)
$(MAKEINSTALL): POPULATED
@if [ ! -u $(MAKEINSTALL) ]; then \
${MAKE} rootid || (echo "You must, as root, do a \
'make makeinstall'. \
This will install /usr/release/bin with \
the appropriate programs which allow a lang boot \
to run" | fmt; false); \
cd ${RELEASE_SRC}; $(MAKE) install; \
else \
cd ${RELEASE_SRC}; $(MAKEINSTALL); \
fi
rootid:
@if [ "`whoami`x" != "root"x ] ; then \
false; \
fi
#########################
#
# STEP 2: INCBOOT
#
# The reason we do this is to make sure all the
# include files are populated correctly. Also, they really have
# to overlay our running system. Right now, this involves
# going into the include directory and doing an install as root
# of include.
#
incboot: INCBOOT
INCBOOT: UTIL_BOOT
@${MAKE} unmount
cd include; ${MAKEINSTALL} DESTDIR=
@${ECHO} "Made INCBOOT on" `${DATE}` > $@
#########################
#
# STEP 3: LANGBOOT
#
# This requires that the program /usr/release/bin/winstall
# exists. This program is suid root, because lang boot wipes the current
# system's libraries and compilers.
#
langboot: LANGBOOT
LANGBOOT: INCBOOT
@${MAKE} unmount
@set -x;CWD=`pwd`;case `mach` in \
mc68010|mc68020) \
cd lang/boot; ${MAKE} $(MFLAGS) CPU=m68k SRCROOT=$$CWD;;\
sparc) \
cd lang/boot; ${MAKE} $(MFLAGS) CPU=sparc SRCROOT=$$CWD;;\
esac
@${ECHO} "Langboot done on" `${DATE}` > $@
#########################
#
# STEP 4: BUILD
#
# Generic rules to actually build the subdirectories.
#
lang: POPULATED
@${MAKE} unmount
@set -x;CWD=`pwd`;case `mach` in \
mc68010|mc68020) cd lang; ${MAKE} $(MFLAGS) CPU=m68k SRCROOT=$$CWD;; \
sparc) cd lang; ${MAKE} $(MFLAGS) CPU=sparc SRCROOT=$$CWD;; \
esac
#
# This is a terrible, terrible hack, and I apologize for it. The right
# thing to do is to set the LD_LIBRARY_PATH up front to point to
# the libraries under development. As soon as that's tested, this
# will be fixed.
#
LIBRARIES: POPULATED
@$(MAKE) unmount
@set -x; for i in ${LIBDIR}; do \
(cd $$i; $(MAKE) $(MFLAGS)); \
(cd $$i; $(MAKEINSTALL) $(MFLAGS) DESTDIR= CHOWN=$(CHOWN)); \
done
@${ECHO} "Libraries done on" `${DATE}` > LIBRARIES
$(SUBDIR): POPULATED
@${MAKE} unmount
cd $@; $(MAKE) ${MFLAGS}
#########################
#
# STEP 5: INSTALL
#
# The "proto" target is provided as a convenience; it's important to
# carefully clean out the /proto partition before building the /proto
# file system.
#
install: BUILT install_dirs
@set -x; for i in ${INCLDIR} ${LIBDIR} ${SUBDIR}; do \
(cd $$i; \
$(MAKE) ${MFLAGS} DESTDIR=${DESTDIR} CHOWN=$(CHOWN) install); \
done
@set -x; case `mach` in \
mc680?0) cd lang; \
$(MAKE) $(MFLAGS) install DESTDIR=$(DESTDIR) CPU=m68k;;\
sparc) cd lang; \
$(MAKE) $(MFLAGS) install DESTDIR=$(DESTDIR) CPU=sparc;;\
esac
install_dirs:
@set -x; for i in ${DIRS}; do \
install -d -o bin -m 755 ${DESTDIR}/$$i; \
done
@set -x; for i in ${USRDIRS}; do \
install -d -o bin -m 755 ${DESTDIR}/usr/$$i; \
done
chmod 1777 ${DESTDIR}/tmp ${DESTDIR}/var/tmp
${RM} -f ${DESTDIR}/bin && ln -s usr/bin ${DESTDIR}/bin
${RM} -f ${DESTDIR}/lib && ln -s usr/lib ${DESTDIR}/lib
${RM} -f ${DESTDIR}/sys && ln -s usr/kvm/sys ${DESTDIR}/sys
${RM} -f ${DESTDIR}/usr/ucbinclude && ln -s include ${DESTDIR}/usr/ucbinclude
${RM} -f ${DESTDIR}/usr/ucblib && ln -s lib ${DESTDIR}/usr/ucblib
${RM} -f ${DESTDIR}/usr/src && ln -s share/src ${DESTDIR}/usr/src
userinstall: ${MAKEINSTALL}
${MAKEINSTALL} DESTDIR=${DESTDIR} CHOWN=${CHOWN}
proto: PROTO INTERNATIONAL NWZ CDROM SUNUPGRADE
PROTO: BUILT
@$(MAKE) rootid || (echo "You must make proto as root."; false)
@${MAKE} unmount
@RAW=`egrep /proto /etc/fstab | awk -F/ '{print "/dev/r"$$3}'`; \
if [ ! -n "$$RAW" ]; then \
echo "no device in fstab for /proto?"; \
exit 1; \
fi; \
echo using $$RAW; \
umount /proto; \
newfs $$RAW; \
mount /proto; \
chmod g+s /proto; \
chown root /proto; \
chgrp staff /proto; \
chmod g+s /proto/lost+found
$(MAKE) install DESTDIR=/proto
@echo "Prototype file system built on" `${DATE}` > $@
@echo running ranlib -t on library archives under ${DESTDIR}/usr...
@-for i in "`find ${DESTDIR}/usr -name '*lib*' -name '*\.*a*' \
-type f -print`"; do \
(file $$i | grep archive > /dev/null && ranlib -t $$i); \
done
@echo done
#########################
#
# STEP 6: TAPES
#
# This actually gets done in sundist, and is provided here as a convenience.
#
#
#tapes: PROTO
# @$(MAKE) rootid || (echo "You must make tapes as root."; false)
# @${MAKE} unmount
# @cd sundist; $(MAKE)
# @cd sundist; $(MAKE) quarter_hd_tapes
# @cd sundist; $(MAKE) half_tapes
#
#########################
#
# STEP 6: INTERNATIONALIZE
#
INTERNATIONAL: international
international: PROTO CRYPTKIT Makefile.inter
$(MAKE) $(MFLAGS) DESTDIR=$(DESTDIR) -f Makefile.inter international
@echo "Internationalizationa done on " `${DATE}` > INTERNATIONAL
CRYPTKIT: PROTO Cryptlist
@if [ -f $@ ]; then \
echo "$@ already exists; I mustn't clobber it."; \
echo "Have you already run 'make international?'"; \
false; \
fi
k=`cat Cryptlist`; (cd $(DESTDIR); tar cBfv - $$k) > $@
Cryptlist: PROTO $(CRYPT)
for i in `cat $(CRYPT)`; do \
( cd $(DESTDIR); $(LS) $$i ); \
done > $@
#########################
#
# STEP 7: Nuclear Waste Zone (NWZ)
#
# Move the patches up to proto
#
NWZ: nwz
nwz:
install -d /proto/UNDISTRIBUTED/patches
cd /UNDISTRIBUTED; \
find . -print | cpio -pdlm /proto/UNDISTRIBUTED/patches
@echo "NWZ done on " `${DATE}` > NWZ
#########################
#
# STEP 8: CDROM
# CDROM image for this arch only
#
CDROM: cdrom
cdrom:
cd sundist; ${MAKE}
cd sundist; ${MAKE} cdrom
@echo "CDROM done on " `${DATE}` > CDROM
#########################
#
# STEP 9: sunupgrade
#
SUNUPGRADE: sunupgrade
sunupgrade:
cd sundist; $(MAKE) sunupgrade_target
@echo "SUNUPGRADE done on " `${DATE}` > SUNUPGRADE
#########################
#
# STEP 10: PREINSTALL
#
# This is only used for machines which will ship a preinstalled distribution.
#
preinstall:
@${MAKE} unmount
@cd sundist/pre; $(MAKE)
@echo "See sundist/pre/build-from-suni for build instructions."
clean: POPULATED makelinks
rm -f a.out core *.s *.o
-for i in ${SUBDIR}; do (cd $$i; $(MAKE) ${MFLAGS} clean); done
@set -x;case `mach` in \
mc68010|mc68020)cd lang; $(MAKE) $(MFLAGS) clean CPU=m68k;;\
sparc) cd lang; $(MAKE) $(MFLAGS) clean CPU=sparc;;\
esac
FRC:

18
Makefile.inter Normal file
View File

@@ -0,0 +1,18 @@
#
# @(#)Makefile.inter 1.1 92/07/30 SMI
#
# For international releases, things that do encryption are either
# modified or removed altogether.
#
DESTDIR=/proto
ARCH=`arch`
IDIRS= lib/libc usr.lib/librpcsvc bin usr.bin usr.bin/ex usr.bin/des \
usr.etc/keyserv usr.etc
IFLAGS= "-Dcbc_crypt=_C0095A2A -Decb_crypt=_C0095A2B \
-Dxencrypt=_C0095A2C -Dxdecrypt=_C0095A2D"
international:
for i in $(IDIRS); do \
(cd $$i; $(MAKE) $(MFLAGS) IFLAGS=$(IFLAGS) \
DESTDIR=$(DESTDIR) international); \
done

11
README Normal file
View File

@@ -0,0 +1,11 @@
This is the SunOS 4.1.3 SUNSRC CD-ROM. It contains the source in 3 forms.
1. plain text source, as a ufs tree, rooted at the top level of
this filesystem. Symlinks to the SCCS hierarchy are in place.
2. SCCS hierarchy, rooted at SCCS_DIRECTORIES.
3. a tar image of the SCCS hierarchy, in a file named 4.1.3_SUNSRC.tar.
This is rooted at ./SCCS_DIRECTORIES.
Please see the SunOS 4.1.3 Source Installation Guide for further details.

13389
SIDlist/4.1.3.SID Normal file

File diff suppressed because it is too large Load Diff

6
_make Normal file
View File

@@ -0,0 +1,6 @@
# Thu Sep 16 14:11:28 EDT 1993 -- depend
sccs get depend
ERROR [SCCS/s.depend]: `SCCS/s.depend' nonexistent (ut4)
*** Error code 1
make: Fatal error: Command failed for target `depend'
# Thu Sep 16 14:11:34 EDT 1993

19
adm/Makefile Normal file
View File

@@ -0,0 +1,19 @@
#
# @(#)Makefile 1.1 92/07/30 SMI
#
# Files which should exist but be empty in the destination
#
EMPTY= wtmp messages lastlog msgbuf usracct lpd-errs
all:
install:
install -d -o bin -m 755 ${DESTDIR}/var/adm
for i in ${EMPTY}; do (touch ${DESTDIR}/var/adm/$$i); done
-rm -f ${DESTDIR}/usr/adm
-rm -f ${DESTDIR}/etc/adm
-ln -s ../var/adm ${DESTDIR}/usr/adm
-ln -s ../var/adm ${DESTDIR}/etc/adm
clean:

256
bin/Makefile Normal file
View File

@@ -0,0 +1,256 @@
#
# Copyright (c) 1980 Regents of the University of California.
# All rights reserved. The Berkeley software License Agreement
# specifies the terms and conditions for redistribution.
#
# @(#)Makefile 1.1 92/07/30 SMI; from UCB 5.13 85/09/09
#
DESTDIR= /net/squaw/home/au
MACHINES= iAPX286 i386 m68k mc68010 mc68020 pdp11 sparc sun u370 u3b u3b2 \
u3b5 u3b15 vax
ARCHITECTURE= sun2 sun3 sun4 sun386 sun3x sun4c sun4m
CFLAGS= -O
LDFLAGS=
CC= /bin/cc
CHOWN= /usr/etc/chown
DOPRNT= ../lib/libc/stdio/common
MAKE= make CC=${CC}
RM= /usr/bin/rm -f
ROOT= root
SPGRP= daemon
.KEEP_STATE:
# Programs that live in subdirectories, and have makefiles of their own.
#
SUBDIR= awk csh diff make sed sh
# Shell scripts that need only be installed and are never removed.
#
SCRIPT= false true mach
SCRIPTSRC= $(SCRIPT:%=%.sh)
SCRIPTASP= arch
SCRIPTASPSRC= $(SCRIPTASP:%=%.sh)
# C programs that live in the current directory and do not need
# explicit make lines.
#
STD= chgrp cmp domainname dd env \
hostid kill ldd line mkdir mt newgrp nice \
pagesize pwd rm rmail rmdir sync \
tee test who
# C programs that live in the current directory and need explicit make lines.
#
NSTD= ed login mail passwd
# Architecture-specific programs
#
ASP= ps
ASP4MONLY= mpstat mps
# Install directory for architecture-specific programs, absolute path
#
ASDIR= /usr/kvm
# Install directory for architecture-specific programs, relative to /usr/bin
#
RELASDIR= ../kvm
# Programs that must run setuid to root
#
SETUID= login mail newgrp passwd
# Programs that must run set-group-id kmem
#
KMEM=
# Programs that must run set-group-id tty.
#
TTY= wall write
# Programs that must run set-group-id operator.
#
OPERATOR=
# Programs built "static" for disaster recovery and startup.
#
STATIC= bar hostname mv tar
# Programs built "small"
#
chgrp cmp cp domainname dd \
env hostid hostname kill \
line ldd mkdir mt mv newgrp nice pagesize passwd \
${ASP} ${ASP4MONLY} pwd rm rmail rmdir sync tee test who \
wall := LDFLAGS += -n -Bdynamic
all: ${SUBDIR} ${STD} ${NSTD} ${TTY} cp ${STATIC} ${ASP} ${ASP4MONLY}
${SUBDIR}: FRC
cd $@; $(MAKE) ${MFLAGS}
${STD} ${TTY} cp:
${CC} ${LDFLAGS} ${CFLAGS} -o $@ $@.c
${STATIC}: doprnt.o $$@.c
${CC} ${LDFLAGS} -Bstatic ${CFLAGS} -o $@ $@.c doprnt.o
doprnt.o: ${DOPRNT}/doprnt.c
${CC} ${CFLAGS} -c -DFLOAT=0 -I${DOPRNT} ${DOPRNT}/doprnt.c
install: ${STD} ${NSTD} ${TTY} cp ${STATIC} ${SCRIPTSRC} ${ASP} ${ASP4MONLY} \
${SCRIPTASPSRC}
install -d -o bin -m 755 ${DESTDIR}/usr/bin
install -d -o bin -m 755 ${DESTDIR}${ASDIR}
install -s cp ${DESTDIR}/usr/bin/newcp; \
mv ${DESTDIR}/usr/bin/newcp ${DESTDIR}/usr/bin/cp;
$(RM) ${DESTDIR}/usr/bin/mv; cp mv ${DESTDIR}/usr/bin/mv; \
strip ${DESTDIR}/usr/bin/mv; chmod 755 ${DESTDIR}/usr/bin/mv
@set -x; for i in ${SUBDIR}; do \
(cd $$i; $(MAKE) ${MFLAGS} DESTDIR=${DESTDIR} install); done
@set -x; for i in ${SCRIPT}; do (install -c $$i.sh ${DESTDIR}/usr/bin/$$i); \
done
@set -x; for i in ${SCRIPTASP} ; \
do (install -c $$i.sh ${DESTDIR}${ASDIR}/$$i; \
rm -f ${DESTDIR}/usr/bin/$$i; \
/usr/bin/ln -s ${RELASDIR}/$$i ${DESTDIR}/usr/bin/$$i); done
install -s ${STD} ${NSTD} ${TTY} bar hostname tar ${DESTDIR}/usr/bin
@set -x; for i in ${ASP}; do (install -s $$i ${DESTDIR}${ASDIR}/$$i; \
rm -f ${DESTDIR}/usr/bin/$$i; \
/usr/bin/ln -s ${RELASDIR}/$$i ${DESTDIR}/usr/bin/$$i); \
done
case `arch -k` in \
sun4m) \
set -x; for i in ${ASP4MONLY}; do (install -s $$i ${DESTDIR}${ASDIR}/$$i; \
rm -f ${DESTDIR}/usr/bin/$$i; \
/usr/bin/ln -s ${RELASDIR}/$$i ${DESTDIR}/usr/bin/$$i); \
done;; \
esac;
$(RM) ${DESTDIR}/usr/bin/cc; \
/usr/bin/ln -s ../lib/compile ${DESTDIR}/usr/bin/cc
@set -x; for i in ${SETUID}; do ($(CHOWN) root ${DESTDIR}/usr/bin/$$i; \
chmod 4755 ${DESTDIR}/usr/bin/$$i); done
@set -x; list="${KMEM}"; \
for i in $$list; do (chgrp kmem ${DESTDIR}/usr/bin/$$i; \
chmod 2755 ${DESTDIR}/usr/bin/$$i); done
@set -x; for i in ${ASP}; do (chgrp kmem ${DESTDIR}${ASDIR}/$$i; \
chmod 2755 ${DESTDIR}${ASDIR}/$$i); done
case `arch -k` in \
sun4m) \
set -x; for i in ${ASP4MONLY}; do (chgrp kmem ${DESTDIR}${ASDIR}/$$i; \
chmod 2755 ${DESTDIR}${ASDIR}/$$i); done;; \
esac;
@set -x; for i in ${TTY}; do (chgrp tty ${DESTDIR}/usr/bin/$$i; \
chmod 2755 ${DESTDIR}/usr/bin/$$i); done
$(RM) "${DESTDIR}/usr/bin/["; \
/bin/ln ${DESTDIR}/usr/bin/test "${DESTDIR}/usr/bin/["
$(RM) ${DESTDIR}/usr/bin/e; \
/bin/ln ${DESTDIR}/usr/bin/ed ${DESTDIR}/usr/bin/e
$(RM) ${DESTDIR}/usr/bin/red; \
/bin/ln ${DESTDIR}/usr/bin/ed ${DESTDIR}/usr/bin/red
@set -x; for i in ${MACHINES}; do \
/bin/rm -f ${DESTDIR}/usr/bin/$$i; \
/bin/ln -s ${RELASDIR}/$$i ${DESTDIR}/usr/bin/$$i; \
done
@set -x; for i in ${ARCHITECTURE}; do \
/bin/rm -f ${DESTDIR}/usr/bin/$$i; \
/bin/ln -s ${RELASDIR}/$$i ${DESTDIR}/usr/bin/$$i; \
done
$(RM) ${DESTDIR}/usr/bin/chsh; \
/usr/bin/ln ${DESTDIR}/usr/bin/passwd ${DESTDIR}/usr/bin/chsh
$(RM) ${DESTDIR}/usr/bin/chfn; \
/usr/bin/ln ${DESTDIR}/usr/bin/passwd ${DESTDIR}/usr/bin/chfn
$(RM) ${DESTDIR}/usr/bin/yppasswd; \
/usr/bin/ln ${DESTDIR}/usr/bin/passwd ${DESTDIR}/usr/bin/yppasswd
$(RM) ${DESTDIR}/usr/bin/ypchsh; \
/usr/bin/ln ${DESTDIR}/usr/bin/passwd ${DESTDIR}/usr/bin/ypchsh
$(RM) ${DESTDIR}/usr/bin/ypchfn; \
/usr/bin/ln ${DESTDIR}/usr/bin/passwd ${DESTDIR}/usr/bin/ypchfn
# create symlink from for ${DESTDIR}/bin for backward compatability.
# /usr/bin/rm -rf ${DESTDIR}/bin
# /usr/bin/ln -s /usr/bin ${DESTDIR}/bin
international:
$(RM) ed passwd login
$(RM) $(DESTDIR)/usr/bin/chfn
$(RM) $(DESTDIR)/usr/bin/chsh
$(RM) $(DESTDIR)/usr/bin/yppasswd
$(RM) $(DESTDIR)/usr/bin/ypchfn
$(RM) $(DESTDIR)/usr/bin/ypchsh
${CC} ${CFLAGS} -o ed ed.c
(LD_LIBRARY_PATH=$(DESTDIR)/usr/lib; export LD_LIBRARY_PATH; \
${CC} ${CFLAGS} $(IFLAGS) -o login login.c -lrpcsvc)
(LD_LIBRARY_PATH=$(DESTDIR)/usr/lib; export LD_LIBRARY_PATH; \
${CC} ${CFLAGS} $(IFLAGS) -o passwd passwd.c -lrpcsvc)
install -s ed ${DESTDIR}/usr/bin
$(RM) ${DESTDIR}/usr/bin/e
ln ${DESTDIR}/usr/bin/ed ${DESTDIR}/usr/bin/e
$(RM) ${DESTDIR}/usr/bin/red
ln ${DESTDIR}/usr/bin/ed ${DESTDIR}/usr/bin/red
install -s -m 4755 passwd $(DESTDIR)/usr/bin
install -s -m 4755 login $(DESTDIR)/usr/bin
ln $(DESTDIR)/usr/bin/passwd $(DESTDIR)/usr/bin/chsh
ln $(DESTDIR)/usr/bin/passwd $(DESTDIR)/usr/bin/chfn
ln $(DESTDIR)/usr/bin/passwd $(DESTDIR)/usr/bin/yppasswd
ln $(DESTDIR)/usr/bin/passwd $(DESTDIR)/usr/bin/ypchsh
ln $(DESTDIR)/usr/bin/passwd $(DESTDIR)/usr/bin/ypchfn
$(RM) ed passwd login
clean:
$(RM) a.out core *.s *.o errs
for i in ${SUBDIR}; do (cd $$i; $(MAKE) ${MFLAGS} clean); done
$(RM) ${STD} ${NSTD} cp mv
FRC:
# Files listed in ${NSTD} have explicit make lines given below.
ps:
${CC} ${CFLAGS} $(LDFLAGS) -o ps ps.c -lm -lkvm
mps:
case `arch -k` in \
sun4m) \
${CC} ${CFLAGS} $(LDFLAGS) -o mps -I/usr/src/sys mps.c -lm -lkvm ;;\
esac; \
mpstat:
case `arch -k` in \
sun4m) \
${CC} ${CFLAGS} $(LDFLAGS) -o mpstat -I/usr/src/sys mpstat.c -lkvm ;;\
esac; \
ed:
${CC} ${CFLAGS} -DCRYPT -o ed ed.c
rmjob:
${CC} ${CFLAGS} ${LPINC} -c ${LPDIR}/rmjob.c
startdaemon:
${CC} ${CFLAGS} ${LPINC} -c ${LPDIR}/startdaemon.c
common:
${CC} ${CFLAGS} ${LPINC} -c ${LPDIR}/common.c
printcap:
${CC} ${CFLAGS} ${LPINC} -c ${LPDIR}/printcap.c
displayq:
${CC} ${CFLAGS} ${LPINC} -c ${LPDIR}/displayq.c
# Following files have explicit make lines because they
# are big and should be linked to be demand paged.
login:
${CC} ${CFLAGS} -o login login.c -lrpcsvc
passwd:
${CC} ${CFLAGS} -o passwd passwd.c -lrpcsvc
mail:
${CC} ${CFLAGS} -o mail mail.c

52
bin/arch.sh Normal file
View File

@@ -0,0 +1,52 @@
#! /bin/sh
# %Z%%M% %I% %E% SMI
USAGE="Usage: $0 [ -k | archname ]"
case $# in
0) OP=major;;
1) case $1 in
-k) OP=minor;;
sun*) OP=compat;;
*) echo $USAGE;
exit 1;;
esac;;
*) echo $USAGE;
exit 1;;
esac
if [ -f /bin/sun4c ] && /bin/sun4c; then
MINOR=sun4c
elif [ -f /usr/kvm/sun4m ] && /usr/kvm/sun4m; then
MINOR=sun4m
elif [ -f /bin/sun4 ] && /bin/sun4; then
MINOR=sun4
elif [ -f /bin/sun3 ] && /bin/sun3; then
MINOR=sun3
elif [ -f /bin/sun3x ] && /bin/sun3x; then
MINOR=sun3x
elif [ -f /bin/sun386 ] && /bin/sun386; then
MINOR=sun386
elif [ -f /bin/sun2 ] && /bin/sun2; then
MINOR=sun2
else
MINOR=unknown
fi
case $MINOR in
sun2) MAJOR=sun2;;
sun386) MAJOR=sun386;;
sun3*) MAJOR=sun3;;
sun4*) MAJOR=sun4;;
*) MAJOR=unknown;;
esac
case $OP in
major) echo $MAJOR;;
minor) echo $MINOR;;
compat) [ $1 = $MAJOR ] ; exit ;;
esac
exit 0

63
bin/awk/Makefile Normal file
View File

@@ -0,0 +1,63 @@
#
# @(#)Makefile 1.1 92/07/30 SMI; from UCB 4.2 83/07/08
#
.KEEP_STATE:
.FRC:
# Binaries, local binaries, where to install them
BINS = awk
LOCAL_BINS = makeprctab
BINDIR = $(DESTDIR)/usr/bin
LOCAL_HDRS = awk.def y.tab.h awk.h tokendefs
SRC = awk.def awk.g.y awk.lx.l b.c lib.c main.c parse.c \
makeprctab.c freeze.c run.c token.c tran.c
OBJS = awk.lx.o b.o main.o token.o tran.o lib.o run.o \
parse.o proctab.o freeze.o awk.g.o
LOCAL_OBJS = makeprctab.o token.o
LINK_LIBS = -lm
CFLAGS = -O
YFLAGS = -d
all install install_h install_bins install_libs := TARGET = $@
makeprctab := OBJS = $(LOCAL_OBJS)
clean := TARGET = clean LOCAL_HDRS =
# make sure all non-local header files exist
.INIT: $(HDRS) $(LOCAL_HDRS)
all: $(BINS)
$(LOCAL_BINS) $(BINS): $$(OBJS)
$(LINK.c) -o $@ $(OBJS) $(LINK_LIBS)
install: $(BINS)
install -d -o bin -m 755 $(BINDIR)
install -s $(BINS) $(BINDIR)
install_h:
clean:
echo $(TARGET) $(LOCAL_HDRS)
-rm -rf $(LOCAL_BINS) $(BINS) $(LOCAL_OBJS) $(OBJS) \
install_bins install_libs \
core a.out y.tab.h awk.h tokendefs proctab.c
y.tab.h: awk.g.o
awk.h: y.tab.h
cp y.tab.h awk.h
tokendefs: y.tab.h tokenscript
rm -f tokendefs
ed - <tokenscript
proctab.c: makeprctab
makeprctab >proctab.c

127
bin/awk/awk.def Normal file
View File

@@ -0,0 +1,127 @@
/* @(#)awk.def 1.1 92/07/30 SMI; from S5R2 */
#define xfree(a) { if(a!=NULL) { yfree(a); a=NULL;} }
#define yfree free
#ifdef DEBUG
# define dprintf if(dbg)printf
#else
# define dprintf(x1, x2, x3, x4)
#endif
typedef double awkfloat;
extern char **FS;
extern char **RS;
extern char **ORS;
extern char **OFS;
extern char **OFMT;
extern awkfloat *NR;
extern awkfloat *NF;
extern char **FILENAME;
extern char record[];
extern int dbg;
extern int lineno;
extern int errorflag;
extern int donefld; /* 1 if record broken into fields */
extern int donerec; /* 1 if record is valid (no fld has changed */
/* CELL: all information about a variable or constant */
typedef struct val {
char ctype; /* CELL, BOOL, JUMP, etc. */
char csub; /* subtype of ctype */
char *nval; /* name, for variables only */
char *sval; /* string value */
awkfloat fval; /* value as number */
unsigned tval; /* type info */
struct val *nextval; /* ptr to next if chained */
} CELL;
extern CELL *symtab[];
extern CELL *setsymtab(), *lookup(), **makesymtab();
extern CELL *recloc; /* location of input record */
extern CELL *nrloc; /* NR */
extern CELL *nfloc; /* NF */
extern CELL *maxmfld; /* pointer to CELL for maximum field assigned to */
/* CELL.tval values: */
#define STR 01 /* string value is valid */
#define NUM 02 /* number value is valid */
#define FLD 04 /* FLD means don't free string space */
#define CON 010 /* this is a constant */
#define ARR 020 /* this is an array */
awkfloat setfval(), getfval();
char *setsval(), *getsval();
char *tostring(), *tokname(), *malloc();
double log(), sqrt(), exp(), atof();
/* function types */
#define FLENGTH 1
#define FSQRT 2
#define FEXP 3
#define FLOG 4
#define FINT 5
#define BOTCH 1
typedef struct nd {
char ntype;
char subtype;
struct nd *nnext;
int nobj;
struct nd *narg[BOTCH]; /* C won't take a zero length array */
} NODE;
extern NODE *winner;
/* ctypes */
#define OCELL 1
#define OBOOL 2
#define OJUMP 3
/* CELL subtypes */
#define CCON 5
#define CTEMP 4
#define CNAME 3
#define CVAR 2
#define CFLD 1
/* bool subtypes */
#define BTRUE 1
#define BFALSE 2
/* jump subtypes */
#define JEXIT 1
#define JNEXT 2
#define JBREAK 3
#define JCONT 4
/* node types */
#define NVALUE 1
#define NSTAT 2
#define NEXPR 3
extern CELL *(*proctab[])();
extern int pairstack[], paircnt;
#define cantexec(n) (n->ntype == NVALUE)
#define notlegal(n) (n <= FIRSTTOKEN || n >= LASTTOKEN || proctab[n-FIRSTTOKEN]== nullproc)
#define isexpr(n) (n->ntype == NEXPR)
#define isjump(n) (n->ctype == OJUMP)
#define isexit(n) (n->ctype == OJUMP && n->csub == JEXIT)
#define isbreak(n) (n->ctype == OJUMP && n->csub == JBREAK)
#define iscont(n) (n->ctype == OJUMP && n->csub == JCONT)
#define isnext(n) (n->ctype == OJUMP && n->csub == JNEXT)
#define isstr(n) (n->tval & STR)
#define isnum(n) (n->tval & NUM)
#define istrue(n) (n->ctype == OBOOL && n->csub == BTRUE)
#define istemp(n) (n->ctype == OCELL && n->csub == CTEMP)
#define isfld(n) (!donefld && n->csub==CFLD && n->ctype==OCELL && n->nval==0)
#define isrec(n) (donefld && n->csub==CFLD && n->ctype==OCELL && n->nval!=0)
extern CELL *nullproc();
extern CELL *relop();
#define MAXSYM 50
#define HAT 0177 /* matches ^ in regular expr */
/* watch out for mach dep */

277
bin/awk/awk.g.y Normal file
View File

@@ -0,0 +1,277 @@
/* @(#)awk.g.y 1.1 92/07/30 SMI; from S5R2 */
%token FIRSTTOKEN /*must be first*/
%token FINAL FATAL
%token LT LE GT GE EQ NE
%token MATCH NOTMATCH
%token APPEND
%token ADD MINUS MULT DIVIDE MOD UMINUS
%token ASSIGN ADDEQ SUBEQ MULTEQ DIVEQ MODEQ
%token JUMP
%token XBEGIN XEND
%token NL
%token PRINT PRINTF SPRINTF SPLIT
%token IF ELSE WHILE FOR IN NEXT EXIT BREAK CONTINUE
%token PROGRAM PASTAT PASTAT2
%right ASGNOP
%left BOR
%left AND
%left NOT
%left NUMBER VAR ARRAY FNCN SUBSTR LSUBSTR INDEX
%left GETLINE
%nonassoc RELOP MATCHOP
%left OR
%left STRING DOT CCL NCCL CHAR
%left '(' '^' '$'
%left CAT
%left '+' '-'
%left '*' '/' '%'
%left STAR PLUS QUEST
%left POSTINCR PREINCR POSTDECR PREDECR INCR DECR
%left FIELD INDIRECT
%token JUMPTRUE JUMPFALSE PUSH GETREC
%token NEWSTAT
%token IN_INIT IN_EXIT
%token LASTTOKEN /* has to be last */
%{
#include "awk.def"
#ifndef DEBUG
# define PUTS(x)
#endif
%}
%%
program:
begin pa_stats end { if (errorflag==0) winner = (NODE *)stat3(PROGRAM, $1, $2, $3); }
| error { yyclearin; yyerror("bailing out"); }
;
begin:
XBEGIN '{' stat_list '}' { $$ = $3; }
| begin NL
| { $$ = (int) 0; }
;
end:
XEND '{' stat_list '}' { $$ = $3; }
| end NL
| { $$ = (int) 0; }
;
compound_conditional:
conditional BOR conditional { $$ = op2(BOR, $1, $3); }
| conditional AND conditional { $$ = op2(AND, $1, $3); }
| NOT conditional { $$ = op1(NOT, $2); }
| '(' compound_conditional ')' { $$ = $2; }
;
compound_pattern:
pattern BOR pattern { $$ = op2(BOR, $1, $3); }
| pattern AND pattern { $$ = op2(AND, $1, $3); }
| NOT pattern { $$ = op1(NOT, $2); }
| '(' compound_pattern ')' { $$ = $2; }
;
conditional:
expr { $$ = op2(NE, $1, valtonode(lookup("$zero&null", symtab, 0), CCON)); }
| rel_expr
| lex_expr
| compound_conditional
;
else:
ELSE optNL
;
field:
FIELD { $$ = valtonode($1, CFLD); }
| INDIRECT term { $$ = op1(INDIRECT, $2); }
;
if:
IF '(' conditional ')' optNL { $$ = $3; }
;
lex_expr:
expr MATCHOP regular_expr { $$ = op2($2, $1, makedfa($3)); }
| '(' lex_expr ')' { $$ = $2; }
;
var:
NUMBER { $$ = valtonode($1, CCON); }
| STRING { $$ = valtonode($1, CCON); }
| VAR { $$ = valtonode($1, CVAR); }
| VAR '[' expr ']' { $$ = op2(ARRAY, $1, $3); }
| field
;
term:
var
| GETLINE { $$ = op1(GETLINE, 0); }
| FNCN {
$$ = op2(FNCN, $1, valtonode(lookup("$record", symtab, 0), CFLD));
}
| FNCN '(' ')' {
$$ = op2(FNCN, $1, valtonode(lookup("$record", symtab, 0), CFLD));
}
| FNCN '(' expr ')' { $$ = op2(FNCN, $1, $3); }
| SPRINTF print_list { $$ = op1($1, $2); }
| SUBSTR '(' expr ',' expr ',' expr ')'
{ $$ = op3(SUBSTR, $3, $5, $7); }
| SUBSTR '(' expr ',' expr ')'
{ $$ = op3(SUBSTR, $3, $5, 0); }
| SPLIT '(' expr ',' VAR ',' expr ')'
{ $$ = op3(SPLIT, $3, $5, $7); }
| SPLIT '(' expr ',' VAR ')'
{ $$ = op3(SPLIT, $3, $5, 0); }
| INDEX '(' expr ',' expr ')'
{ $$ = op2(INDEX, $3, $5); }
| '(' expr ')' {$$ = $2; }
| term '+' term { $$ = op2(ADD, $1, $3); }
| term '-' term { $$ = op2(MINUS, $1, $3); }
| term '*' term { $$ = op2(MULT, $1, $3); }
| term '/' term { $$ = op2(DIVIDE, $1, $3); }
| term '%' term { $$ = op2(MOD, $1, $3); }
| '-' term %prec QUEST { $$ = op1(UMINUS, $2); }
| '+' term %prec QUEST { $$ = $2; }
| INCR var { $$ = op1(PREINCR, $2); }
| DECR var { $$ = op1(PREDECR, $2); }
| var INCR { $$= op1(POSTINCR, $1); }
| var DECR { $$= op1(POSTDECR, $1); }
;
expr:
term
| expr term { $$ = op2(CAT, $1, $2); }
| var ASGNOP expr { $$ = op2($2, $1, $3); }
;
optNL:
NL
|
;
pa_stat:
pattern { $$ = stat2(PASTAT, $1, genprint()); }
| pattern '{' stat_list '}' { $$ = stat2(PASTAT, $1, $3); }
| pattern ',' pattern { $$ = pa2stat($1, $3, genprint()); }
| pattern ',' pattern '{' stat_list '}'
{ $$ = pa2stat($1, $3, $5); }
| '{' stat_list '}' { $$ = stat2(PASTAT, 0, $2); }
;
pa_stats:
pa_stats pa_stat st { $$ = linkum($1, $2); }
| { $$ = (int)0; }
| pa_stats pa_stat { $$ = linkum($1, $2); }
;
pattern:
regular_expr {
$$ = op2(MATCH, valtonode(lookup("$record", symtab, 0), CFLD), makedfa($1));
}
| rel_expr
| lex_expr
| compound_pattern
;
print_list:
expr
| pe_list
| { $$ = valtonode(lookup("$record", symtab, 0), CFLD); }
;
pe_list:
expr ',' expr {$$ = linkum($1, $3); }
| pe_list ',' expr {$$ = linkum($1, $3); }
| '(' pe_list ')' {$$ = $2; }
;
redir:
RELOP
| '|'
;
regular_expr:
'/' { startreg(); }
r '/'
{ $$ = $3; }
;
r:
CHAR { $$ = op2(CHAR, (NODE *) 0, $1); }
| DOT { $$ = op2(DOT, (NODE *) 0, (NODE *) 0); }
| CCL { $$ = op2(CCL, (NODE *) 0, cclenter($1)); }
| NCCL { $$ = op2(NCCL, (NODE *) 0, cclenter($1)); }
| '^' { $$ = op2(CHAR, (NODE *) 0, HAT); }
| '$' { $$ = op2(CHAR, (NODE *) 0, (NODE *) 0); }
| r OR r { $$ = op2(OR, $1, $3); }
| r r %prec CAT
{ $$ = op2(CAT, $1, $2); }
| r STAR { $$ = op2(STAR, $1, (NODE *) 0); }
| r PLUS { $$ = op2(PLUS, $1, (NODE *) 0); }
| r QUEST { $$ = op2(QUEST, $1, (NODE *) 0); }
| '(' r ')' { $$ = $2; }
;
rel_expr:
expr RELOP expr
{ $$ = op2($2, $1, $3); }
| '(' rel_expr ')'
{ $$ = $2; }
;
st:
NL
| ';'
;
simple_stat:
PRINT print_list redir expr
{ $$ = stat3($1, $2, $3, $4); }
| PRINT print_list
{ $$ = stat3($1, $2, 0, 0); }
| PRINTF print_list redir expr
{ $$ = stat3($1, $2, $3, $4); }
| PRINTF print_list
{ $$ = stat3($1, $2, 0, 0); }
| expr { $$ = exptostat($1); }
| { $$ = (int)0; }
| error { yyclearin; yyerror("illegal statement"); $$ = (int)0; }
;
statement:
simple_stat st
| if statement { $$ = stat3(IF, $1, $2, 0); }
| if statement else statement
{ $$ = stat3(IF, $1, $2, $4); }
| while statement { $$ = stat2(WHILE, $1, $2); }
| for
| NEXT st { $$ = stat1(NEXT, 0); }
| EXIT st { $$ = stat1(EXIT, 0); }
| EXIT expr st { $$ = stat1(EXIT, $2); }
| BREAK st { $$ = stat1(BREAK, 0); }
| CONTINUE st { $$ = stat1(CONTINUE, 0); }
| '{' stat_list '}' { $$ = $2; }
;
stat_list:
stat_list statement { $$ = linkum($1, $2); }
| { $$ = (int)0; }
;
while:
WHILE '(' conditional ')' optNL { $$ = $3; }
;
for:
FOR '(' simple_stat ';' conditional ';' simple_stat ')' optNL statement
{ $$ = stat4(FOR, $3, $5, $7, $10); }
| FOR '(' simple_stat ';' ';' simple_stat ')' optNL statement
{ $$ = stat4(FOR, $3, 0, $6, $9); }
| FOR '(' VAR IN VAR ')' optNL statement
{ $$ = stat3(IN, $3, $5, $8); }
;
%%

181
bin/awk/awk.lx.l Normal file
View File

@@ -0,0 +1,181 @@
/* @(#)awk.lx.l 1.1 92/07/30 SMI; from S5R2 */
%Start A str chc sc reg comment
%{
#include "awk.h"
#include "awk.def"
#undef input /* defeat lex */
extern int yylval;
extern int mustfld;
int lineno = 1;
#ifdef DEBUG
# define RETURN(x) {if (dbg) ptoken(x); return(x); }
#else
# define RETURN(x) return(x)
#endif
#define CADD cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;}
#define CBUFLEN 150
char cbuf[CBUFLEN];
int clen, cflag;
%}
A [a-zA-Z_]
B [a-zA-Z0-9_]
D [0-9]
WS [ \t]
%%
switch (yybgin-yysvec-1) { /* witchcraft */
case 0:
BEGIN A;
break;
case sc:
BEGIN A;
RETURN('}');
}
<A>^\n lineno++;
<A>^{WS}*#.*\n lineno++; /* strip comment lines */
<A>{WS} ;
<A,reg>"\\"\n lineno++;
<A>"||" RETURN(BOR);
<A>BEGIN RETURN(XBEGIN);
<A>END RETURN(XEND);
<A>PROGEND RETURN(EOF);
<A>"&&" RETURN(AND);
<A>"!" RETURN(NOT);
<A>"!=" { yylval = NE; RETURN(RELOP); }
<A>"~" { yylval = MATCH; RETURN(MATCHOP); }
<A>"!~" { yylval = NOTMATCH; RETURN(MATCHOP); }
<A>"<" { yylval = LT; RETURN(RELOP); }
<A>"<=" { yylval = LE; RETURN(RELOP); }
<A>"==" { yylval = EQ; RETURN(RELOP); }
<A>">=" { yylval = GE; RETURN(RELOP); }
<A>">" { yylval = GT; RETURN(RELOP); }
<A>">>" { yylval = APPEND; RETURN(RELOP); }
<A>"++" { yylval = INCR; RETURN(INCR); }
<A>"--" { yylval = DECR; RETURN(DECR); }
<A>"+=" { yylval = ADDEQ; RETURN(ASGNOP); }
<A>"-=" { yylval = SUBEQ; RETURN(ASGNOP); }
<A>"*=" { yylval = MULTEQ; RETURN(ASGNOP); }
<A>"/=" { yylval = DIVEQ; RETURN(ASGNOP); }
<A>"%=" { yylval = MODEQ; RETURN(ASGNOP); }
<A>"=" { yylval = ASSIGN; RETURN(ASGNOP); }
<A>"$"{D}+ { if (atoi(yytext+1)==0) {
yylval = (int)lookup("$record", symtab, 0);
RETURN(STRING);
} else {
yylval = fieldadr(atoi(yytext+1));
RETURN(FIELD);
}
}
<A>"$"{WS}* { RETURN(INDIRECT); }
<A>NF { mustfld=1; yylval = (int)setsymtab(yytext, NULL, 0.0, NUM, symtab); RETURN(VAR); }
<A>({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)? {
yylval = (int)setsymtab(yytext, NULL, atof(yytext), CON|NUM, symtab); RETURN(NUMBER); }
<A>"}"{WS}*\n { BEGIN sc; lineno++; RETURN(';'); }
<A>"}" { BEGIN sc; RETURN(';'); }
<A>;\n { lineno++; RETURN(';'); }
<A>\n { lineno++; RETURN(NL); }
<A>while RETURN(WHILE);
<A>for RETURN(FOR);
<A>if RETURN(IF);
<A>else RETURN(ELSE);
<A>next RETURN(NEXT);
<A>exit RETURN(EXIT);
<A>break RETURN(BREAK);
<A>continue RETURN(CONTINUE);
<A>print { yylval = PRINT; RETURN(PRINT); }
<A>printf { yylval = PRINTF; RETURN(PRINTF); }
<A>sprintf { yylval = SPRINTF; RETURN(SPRINTF); }
<A>split { yylval = SPLIT; RETURN(SPLIT); }
<A>substr RETURN(SUBSTR);
<A>index RETURN(INDEX);
<A>in RETURN(IN);
<A>getline RETURN(GETLINE);
<A>length { yylval = FLENGTH; RETURN(FNCN); }
<A>log { yylval = FLOG; RETURN(FNCN); }
<A>int { yylval = FINT; RETURN(FNCN); }
<A>exp { yylval = FEXP; RETURN(FNCN); }
<A>sqrt { yylval = FSQRT; RETURN(FNCN); }
<A>{A}{B}* { yylval = (int)setsymtab(yytext, tostring(""), 0.0, STR|NUM, symtab); RETURN(VAR); }
<A>\" { BEGIN str; clen=0; }
<A># { BEGIN comment; }
<comment>\n { BEGIN A; lineno++; RETURN(NL); }
<comment>. ;
<A>. { yylval = yytext[0]; RETURN(yytext[0]); }
<reg>"[" { BEGIN chc; clen=0; cflag=0; }
<reg>"[^" { BEGIN chc; clen=0; cflag=1; }
<reg>"?" RETURN(QUEST);
<reg>"+" RETURN(PLUS);
<reg>"*" RETURN(STAR);
<reg>"|" RETURN(OR);
<reg>"." RETURN(DOT);
<reg>"(" RETURN('(');
<reg>")" RETURN(')');
<reg>"^" RETURN('^');
<reg>"$" RETURN('$');
<reg>\\{D}{D}{D} { sscanf(yytext+1, "%o", &yylval); RETURN(CHAR); }
<reg>\\. { if (yytext[1]=='n') yylval = '\n';
else if (yytext[1] == 't') yylval = '\t';
else if (yytext[1] == 'b') yylval = '\b';
else if (yytext[1] == 'r') yylval = '\r';
else if (yytext[1] == 'f') yylval = '\f';
else yylval = yytext[1];
RETURN(CHAR);
}
<reg>"/" { BEGIN A; unput('/'); }
<reg>\n { yyerror("newline in regular expression"); lineno++; BEGIN A; }
<reg>. { yylval = yytext[0]; RETURN(CHAR); }
<str>\" { char *s; BEGIN A; cbuf[clen]=0; s = tostring(cbuf);
cbuf[clen] = ' '; cbuf[++clen] = 0;
yylval = (int)setsymtab(cbuf, s, 0.0, CON|STR, symtab); RETURN(STRING); }
<str>\n { yyerror("newline in string"); lineno++; BEGIN A; }
<str>"\\\"" { cbuf[clen++]='"'; }
<str,chc>"\\"n { cbuf[clen++]='\n'; }
<str,chc>"\\"t { cbuf[clen++]='\t'; }
<str,chc>"\\"b { cbuf[clen++]='\b'; }
<str,chc>"\\"r { cbuf[clen++]='\r'; }
<str,chc>"\\"f { cbuf[clen++]='\f'; }
<str,chc>"\\\\" { cbuf[clen++]='\\'; }
<str>. { CADD; }
<chc>"\\""]" { cbuf[clen++]=']'; }
<chc>"]" { BEGIN reg; cbuf[clen]=0; yylval = (int)tostring(cbuf);
if (cflag==0) { RETURN(CCL); }
else { RETURN(NCCL); } }
<chc>\n { yyerror("newline in character class"); lineno++; BEGIN A; }
<chc>. { CADD; }
%%
input()
{
register c;
extern char *lexprog;
if (yysptr > yysbuf)
c = U(*--yysptr);
else if (yyin == NULL)
c = *lexprog++;
else
c = getc(yyin);
if (c == '\n')
yylineno++;
else if (c == EOF)
c = 0;
return(c);
}
startreg()
{
BEGIN reg;
}

539
bin/awk/b.c Normal file
View File

@@ -0,0 +1,539 @@
#ifndef lint
static char sccsid[] = "@(#)b.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "awk.def"
#include "stdio.h"
#include "awk.h"
extern NODE *op2();
extern struct fa *cgotofn();
#define MAXLIN 256
#define NCHARS 128
#define NSTATES 256
#define type(v) v->nobj
#define left(v) v->narg[0]
#define right(v) v->narg[1]
#define parent(v) v->nnext
#define LEAF case CCL: case NCCL: case CHAR: case DOT:
#define UNARY case FINAL: case STAR: case PLUS: case QUEST:
/* encoding in tree NODEs:
leaf (CCL, NCCL, CHAR, DOT): left is index, right contains value or pointer to value
unary (FINAL, STAR, PLUS, QUEST): left is child, right is null
binary (CAT, OR): left and right are children
parent contains pointer to parent
*/
struct fa {
int cch;
struct fa *st;
};
int *state[NSTATES];
int *foll[MAXLIN];
char chars[MAXLIN];
int setvec[MAXLIN];
NODE *point[MAXLIN];
int setcnt;
int line;
struct fa *makedfa(p) /* returns dfa for tree pointed to by p */
NODE *p;
{
NODE *p1;
struct fa *fap;
p1 = op2(CAT, op2(STAR, op2(DOT, (NODE *) 0, (NODE *) 0), (NODE *) 0), p);
/* put DOT STAR in front of reg. exp. */
p1 = op2(FINAL, p1, (NODE *) 0); /* install FINAL NODE */
line = 0;
penter(p1); /* enter parent pointers and leaf indices */
point[line] = p1; /* FINAL NODE */
setvec[0] = 1; /* for initial DOT STAR */
cfoll(p1); /* set up follow sets */
fap = cgotofn();
freetr(p1); /* add this when alloc works */
return(fap);
}
penter(p) /* set up parent pointers and leaf indices */
NODE *p;
{
switch(type(p)) {
LEAF
left(p) = (NODE *) line;
point[line++] = p;
break;
UNARY
penter(left(p));
parent(left(p)) = p;
break;
case CAT:
case OR:
penter(left(p));
penter(right(p));
parent(left(p)) = p;
parent(right(p)) = p;
break;
default:
error(FATAL, "unknown type %d in penter\n", type(p));
break;
}
}
freetr(p) /* free parse tree and follow sets */
NODE *p;
{
switch(type(p)) {
LEAF
xfree(foll[(int) left(p)]);
xfree(p);
break;
UNARY
freetr(left(p));
xfree(p);
break;
case CAT:
case OR:
freetr(left(p));
freetr(right(p));
xfree(p);
break;
default:
error(FATAL, "unknown type %d in freetr", type(p));
break;
}
}
char *cclenter(p)
register char *p;
{
register i, c;
char *op;
op = p;
i = 0;
while ((c = *p++) != 0) {
if (c == '-' && i > 0 && chars[i-1] != 0) {
if (*p != 0) {
c = chars[i-1];
while (c < *p) {
if (i >= MAXLIN)
overflo();
chars[i++] = ++c;
}
p++;
continue;
}
}
if (i >= MAXLIN)
overflo();
chars[i++] = c;
}
chars[i++] = '\0';
dprintf("cclenter: in = |%s|, out = |%s|\n", op, chars, NULL);
xfree(op);
return(tostring(chars));
}
overflo()
{
error(FATAL, "regular expression too long\n");
}
cfoll(v) /* enter follow set of each leaf of vertex v into foll[leaf] */
register NODE *v;
{
register i;
int prev;
int *add();
switch(type(v)) {
LEAF
setcnt = 0;
for (i=1; i<=line; i++)
setvec[i] = 0;
follow(v);
if (notin(foll, ( (int) left(v))-1, &prev)) {
foll[(int) left(v)] = add(setcnt);
}
else
foll[ (int) left(v)] = foll[prev];
break;
UNARY
cfoll(left(v));
break;
case CAT:
case OR:
cfoll(left(v));
cfoll(right(v));
break;
default:
error(FATAL, "unknown type %d in cfoll", type(v));
}
}
first(p) /* collects initially active leaves of p into setvec */
register NODE *p; /* returns 0 or 1 depending on whether p matches empty string */
{
register b;
switch(type(p)) {
LEAF
if (setvec[(int) left(p)] != 1) {
setvec[(int) left(p)] = 1;
setcnt++;
}
if (type(p) == CCL && (*(char *) right(p)) == '\0')
return(0); /* empty CCL */
else return(1);
case FINAL:
case PLUS:
if (first(left(p)) == 0) return(0);
return(1);
case STAR:
case QUEST:
first(left(p));
return(0);
case CAT:
if (first(left(p)) == 0 && first(right(p)) == 0) return(0);
return(1);
case OR:
b = first(right(p));
if (first(left(p)) == 0 || b == 0) return(0);
return(1);
}
error(FATAL, "unknown type %d in first\n", type(p));
return(-1);
}
follow(v)
NODE *v; /* collects leaves that can follow v into setvec */
{
NODE *p;
if (type(v) == FINAL)
return;
p = parent(v);
switch (type(p)) {
case STAR:
case PLUS: first(v);
follow(p);
return;
case OR:
case QUEST: follow(p);
return;
case CAT: if (v == left(p)) { /* v is left child of p */
if (first(right(p)) == 0) {
follow(p);
return;
}
}
else /* v is right child */
follow(p);
return;
case FINAL: if (setvec[line] != 1) {
setvec[line] = 1;
setcnt++;
}
return;
}
}
member(c, s) /* is c in s? */
register char c, *s;
{
while (*s)
if (c == *s++)
return(1);
return(0);
}
notin(array, n, prev) /* is setvec in array[0] thru array[n]? */
int **array;
int *prev; {
register i, j;
int *ptr;
for (i=0; i<=n; i++) {
ptr = array[i];
if (*ptr == setcnt) {
for (j=0; j < setcnt; j++)
if (setvec[*(++ptr)] != 1) goto nxt;
*prev = i;
return(0);
}
nxt: ;
}
return(1);
}
int *add(n) { /* remember setvec */
int *ptr, *p;
register i;
if ((p = ptr = (int *) malloc((n+1)*sizeof(int))) == NULL)
overflo();
*ptr = n;
dprintf("add(%d)\n", n, NULL, NULL);
for (i=1; i <= line; i++)
if (setvec[i] == 1) {
*(++ptr) = i;
dprintf(" ptr = %o, *ptr = %d, i = %d\n", ptr, *ptr, i);
}
dprintf("\n", NULL, NULL, NULL);
return(p);
}
struct fa *cgotofn()
{
register i, k;
register int *ptr;
char c;
char *p;
NODE *cp;
int j, n, s, ind, numtrans;
int finflg;
int curpos, num, prev;
struct fa *where[NSTATES];
int fatab[257];
struct fa *pfa;
char index[MAXLIN];
char iposns[MAXLIN];
int sposns[MAXLIN];
int spmax, spinit;
char symbol[NCHARS];
char isyms[NCHARS];
char ssyms[NCHARS];
int ssmax, ssinit;
for (i=0; i<=line; i++) index[i] = iposns[i] = setvec[i] = 0;
for (i=0; i<NCHARS; i++) isyms[i] = symbol[i] = 0;
setcnt = 0;
/* compute initial positions and symbols of state 0 */
ssmax = 0;
ptr = state[0] = foll[0];
spinit = *ptr;
for (i=0; i<spinit; i++) {
curpos = *(++ptr);
sposns[i] = curpos;
iposns[curpos] = 1;
cp = point[curpos];
dprintf("i = %d, spinit = %d, curpos = %d\n", i, spinit, curpos);
switch (type(cp)) {
case CHAR:
k = (int) right(cp);
if (isyms[k] != 1) {
isyms[k] = 1;
ssyms[ssmax++] = k;
}
break;
case DOT:
for (k=1; k<NCHARS; k++) {
if (k != HAT) {
if (isyms[k] != 1) {
isyms[k] = 1;
ssyms[ssmax++] = k;
}
}
}
break;
case CCL:
for (p = (char *) right(cp); *p; p++) {
if (*p != HAT) {
if (isyms[*p] != 1) {
isyms[*p] = 1;
ssyms[ssmax++] = *p;
}
}
}
break;
case NCCL:
for (k=1; k<NCHARS; k++) {
if (k != HAT && !member(k, (char *) right(cp))) {
if (isyms[k] != 1) {
isyms[k] = 1;
ssyms[ssmax++] = k;
}
}
}
}
}
ssinit = ssmax;
n = 0;
for (s=0; s<=n; s++) {
dprintf("s = %d\n", s, NULL, NULL);
ind = 0;
numtrans = 0;
finflg = 0;
if (*(state[s] + *state[s]) == line) { /* s final? */
finflg = 1;
goto tenter;
}
spmax = spinit;
ssmax = ssinit;
ptr = state[s];
num = *ptr;
for (i=0; i<num; i++) {
curpos = *(++ptr);
if (iposns[curpos] != 1 && index[curpos] != 1) {
index[curpos] = 1;
sposns[spmax++] = curpos;
}
cp = point[curpos];
switch (type(cp)) {
case CHAR:
k = (int) right(cp);
if (isyms[k] == 0 && symbol[k] == 0) {
symbol[k] = 1;
ssyms[ssmax++] = k;
}
break;
case DOT:
for (k=1; k<NCHARS; k++) {
if (k != HAT) {
if (isyms[k] == 0 && symbol[k] == 0) {
symbol[k] = 1;
ssyms[ssmax++] = k;
}
}
}
break;
case CCL:
for (p = (char *) right(cp); *p; p++) {
if (*p != HAT) {
if (isyms[*p] == 0 && symbol[*p] == 0) {
symbol[*p] = 1;
ssyms[ssmax++] = *p;
}
}
}
break;
case NCCL:
for (k=1; k<NCHARS; k++) {
if (k != HAT && !member(k, (char *) right(cp))) {
if (isyms[k] == 0 && symbol[k] == 0) {
symbol[k] = 1;
ssyms[ssmax++] = k;
}
}
}
}
}
for (j=0; j<ssmax; j++) { /* nextstate(s, ssyms[j]) */
c = ssyms[j];
symbol[c] = 0;
setcnt = 0;
for (k=0; k<=line; k++) setvec[k] = 0;
for (i=0; i<spmax; i++) {
index[sposns[i]] = 0;
cp = point[sposns[i]];
if ((k = type(cp)) != FINAL)
if (k == CHAR && c == (int) right(cp)
|| k == DOT
|| k == CCL && member(c, (char *) right(cp))
|| k == NCCL && !member(c, (char *) right(cp))) {
ptr = foll[sposns[i]];
num = *ptr;
for (k=0; k<num; k++) {
if (setvec[*(++ptr)] != 1
&& iposns[*ptr] != 1) {
setvec[*ptr] = 1;
setcnt++;
}
}
}
} /* end nextstate */
if (notin(state, n, &prev)) {
if (n >= NSTATES - 1) {
dprintf("cgotofn: notin; state = %d, n = %d\n", state, n, NULL);
overflo();
}
state[++n] = add(setcnt);
dprintf(" delta(%d,%o) = %d", s,c,n);
dprintf(", ind = %d\n", ind+1, NULL, NULL);
fatab[++ind] = c;
fatab[++ind] = n;
numtrans++;
}
else {
if (prev != 0) {
dprintf(" delta(%d,%o) = %d", s,c,prev);
dprintf(", ind = %d\n", ind+1, NULL, NULL);
fatab[++ind] = c;
fatab[++ind] = prev;
numtrans++;
}
}
}
tenter:
if ((pfa = (struct fa *) malloc((numtrans + 1) * sizeof(struct fa))) == NULL)
overflo();
where[s] = pfa;
if (finflg)
pfa->cch = -1; /* s is a final state */
else
pfa->cch = numtrans;
pfa->st = 0;
for (i=1, pfa += 1; i<=numtrans; i++, pfa++) {
pfa->cch = fatab[2*i-1];
pfa->st = (struct fa *) fatab[2*i];
}
}
for (i=0; i<=n; i++) {
xfree(state[i]); /* free state[i] */
pfa = where[i];
pfa->st = where[0];
dprintf("state %d: (%o)\n", i, pfa, NULL);
dprintf(" numtrans = %d, default = %o\n", pfa->cch, pfa->st, NULL);
for (k=1; k<=pfa->cch; k++) {
(pfa+k)->st = where[ (int) (pfa+k)->st];
dprintf(" char = %o, nextstate = %o\n",(pfa+k)->cch, (pfa+k)->st, NULL);
}
}
pfa = where[0];
if ((num = pfa->cch) < 0)
return(where[0]);
for (pfa += num; num; num--, pfa--)
if (pfa->cch == HAT) {
return(pfa->st);
}
return(where[0]);
}
match(pfa, p)
register struct fa *pfa;
register char *p;
{
register count;
char c;
if (p == 0) return(0);
if (pfa->cch == 1) { /* fast test for first character, if possible */
c = (++pfa)->cch;
do
if (c == *p) {
p++;
pfa = pfa->st;
goto adv;
}
while (*p++ != 0);
return(0);
}
adv: if ((count = pfa->cch) < 0) return(1);
do {
for (pfa += count; count; count--, pfa--)
if (pfa->cch == *p) {
break;
}
pfa = pfa->st;
if ((count = pfa->cch) < 0) return(1);
} while(*p++ != 0);
return(0);
}

36
bin/awk/freeze.c Normal file
View File

@@ -0,0 +1,36 @@
#ifndef lint
static char sccsid[] = "@(#)freeze.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "stdio.h"
freeze(s) char *s;
{ int fd;
unsigned int *len;
len = (unsigned int *)sbrk(0);
if((fd = creat(s, 0666)) < 0) {
perror(s);
return(1);
}
write(fd, &len, sizeof(len));
write(fd, (char *)0, len);
close(fd);
return(0);
}
thaw(s) char *s;
{ int fd;
unsigned int *len;
if(*s == 0) {
fprintf(stderr, "empty restore file\n");
return(1);
}
if((fd = open(s, 0)) < 0) {
perror(s);
return(1);
}
read(fd, &len, sizeof(len));
(void) brk(len);
read(fd, (char *)0, len);
close(fd);
return(0);
}

309
bin/awk/lib.c Normal file
View File

@@ -0,0 +1,309 @@
#ifndef lint
static char sccsid[] = "@(#)lib.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "stdio.h"
#include "awk.def"
#include "awk.h"
#include "ctype.h"
FILE *infile = NULL;
char *file;
#define RECSIZE (5 * 512)
char record[RECSIZE];
char fields[RECSIZE];
static char EMPTY[] = "";
#define MAXFLD 100
int donefld; /* 1 = implies rec broken into fields */
int donerec; /* 1 = record is valid (no flds have changed) */
int mustfld; /* 1 = NF seen, so always break*/
#define FINIT { OCELL, CFLD, 0, EMPTY, 0.0, FLD|STR }
CELL fldtab[MAXFLD] = { /* room for fields */
{ OCELL, CFLD, "$record", record, 0.0, STR|FLD},
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT,
FINIT, FINIT, FINIT, FINIT, FINIT, FINIT, FINIT
};
int maxfld = 0; /* last used field */
CELL *maxmfld = &fldtab[0]; /* pointer to CELL for maximum field assigned to */
getrec()
{
register char *rr, *er;
register c, sep;
register FILE *inf;
extern int svargc;
extern char **svargv;
dprintf("**RS=%o, **FS=%o\n", **RS, **FS, NULL);
donefld = 0;
donerec = 1;
record[0] = 0;
er = record + sizeof(record);
while (svargc > 0) {
dprintf("svargc=%d, *svargv=%s\n", svargc, *svargv, NULL);
if (infile == NULL) { /* have to open a new file */
if (member('=', *svargv)) { /* it's a var=value argument */
setclvar(*svargv);
if (svargc > 1) {
svargv++;
svargc--;
continue;
}
*svargv = "-";
}
*FILENAME = file = *svargv;
dprintf("opening file %s\n", file, NULL, NULL);
if (*file == '-')
infile = stdin;
else if ((infile = fopen(file, "r")) == NULL)
error(FATAL, "can't open %s", file);
}
if ((sep = **RS) == 0)
sep = '\n';
inf = infile;
for (rr = record; ; ) {
for (; (c=getc(inf)) != sep && c != EOF && rr < er;
*rr++ = c)
;
if (rr >= er)
error(FATAL, "record `%.20s...' too long",
record);
if (**RS == sep || c == EOF)
break;
if ((c = getc(inf)) == '\n' || c == EOF) /* 2 in a row */
break;
*rr++ = '\n';
*rr++ = c;
}
if (rr > er)
error(FATAL, "record `%.20s...' too long", record);
*rr = 0;
if (mustfld)
fldbld();
if (c != EOF || rr > record) { /* normal record */
recloc->tval &= ~NUM;
recloc->tval |= STR;
++nrloc->fval;
nrloc->tval &= ~STR;
nrloc->tval |= NUM;
return(1);
}
/* EOF arrived on this file; set up next */
if (infile != stdin)
fclose(infile);
infile = NULL;
svargc--;
svargv++;
}
return(0); /* true end of file */
}
setclvar(s) /* set var=value from s */
char *s;
{
char *p;
CELL *q;
for (p=s; *p != '='; p++)
;
*p++ = 0;
q = setsymtab(s, tostring(p), 0.0, STR, symtab);
setsval(q, p);
dprintf("command line set %s to |%s|\n", s, p, NULL);
}
static int ctest[0200];
fldbld()
{
register char *r, *fr, sep;
CELL *p, *q;
int i, j;
r = record;
fr = fields;
i = 0; /* number of fields accumulated here */
if ((sep = **FS) == ' ')
for (i = 0; ; ) {
while (*r == ' ' || *r == '\t' || *r == '\n')
r++;
if (*r == 0)
break;
i++;
if (i >= MAXFLD)
error(FATAL, "record `%.20s...' has too many fields", record);
if (!(fldtab[i].tval&FLD))
xfree(fldtab[i].sval);
fldtab[i].sval = fr;
fldtab[i].tval = FLD | STR;
ctest[' '] = ctest['\t'] = ctest['\n'] = ctest['\0'] =1;
do
*fr++ = *r++;
/*while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0');*/
while(!ctest[*r]);
ctest[' '] = ctest['\t'] = ctest['\n'] = ctest['\0'] =0;
*fr++ = 0;
}
else if (*r != 0) /* if 0, it's a null field */
for (;;) {
i++;
if (i >= MAXFLD)
error(FATAL, "record `%.20s...' has too many fields", record);
if (!(fldtab[i].tval&FLD))
xfree(fldtab[i].sval);
fldtab[i].sval = fr;
fldtab[i].tval = FLD | STR;
ctest[sep] = ctest['\n'] = ctest['\0'] = 1;
while(!ctest[*r])
/*while (*r != sep && *r != '\n' && *r != '\0')*/
/* \n always a separator */
*fr++ = *r++;
ctest[sep] = ctest['\n'] = ctest['\0'] = 0;
*fr++ = 0;
if (*r++ == 0)
break;
}
*fr = 0;
/* clean out junk from previous record */
for (p = maxmfld, q = &fldtab[i]; p > q; p--) {
if (!(p->tval&FLD))
xfree(p->sval);
p->tval = STR | FLD;
p->sval = EMPTY;
}
maxfld = i;
maxmfld = &fldtab[i];
donefld = 1;
for (i = 1; i <= maxfld; i++)
if(isnumber(fldtab[i].sval)) {
fldtab[i].fval = atof(fldtab[i].sval);
fldtab[i].tval |= NUM;
}
setfval(lookup("NF", symtab, 0), (awkfloat) maxfld);
if (dbg)
for (i = 0; i <= maxfld; i++)
printf("field %d: |%s|\n", i, fldtab[i].sval);
}
recbld()
{
int i;
register char *r, *p;
if (donefld == 0 || donerec == 1)
return;
r = record;
for (i = 1; i <= *NF; i++) {
p = getsval(&fldtab[i]);
while (*r++ = *p++)
;
*(r-1) = **OFS;
}
*(r-1) = '\0';
dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
recloc->tval = STR | FLD;
dprintf("in recbld FS=%o, recloc=%o\n", **FS, recloc, NULL);
if (r > record+RECSIZE)
error(FATAL, "built giant record `%.20s...'", record);
dprintf("recbld = |%s|\n", record, NULL, NULL);
}
CELL *fieldadr(n)
{
if (n < 0 || n >= MAXFLD)
error(FATAL, "trying to access field %d", n);
return(&fldtab[n]);
}
int errorflag = 0;
yyerror(s) char *s; {
fprintf(stderr, "awk: %s near line %d\n", s, lineno);
errorflag = 2;
}
error(f, s, a1, a2, a3, a4, a5, a6, a7) {
fprintf(stderr, "awk: ");
fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
fprintf(stderr, "\n");
if (NR && *NR > 0)
fprintf(stderr, " record number %g\n", *NR);
if (f)
exit(2);
}
PUTS(s) char *s; {
dprintf("%s\n", s, NULL, NULL);
}
#define MAXEXPON 38 /* maximum exponenet for fp number */
isnumber(s)
register char *s;
{
register d1, d2;
int point;
char *es;
d1 = d2 = point = 0;
while (*s == ' ' || *s == '\t' || *s == '\n')
s++;
if (*s == '\0')
return(0); /* empty stuff isn't number */
if (*s == '+' || *s == '-')
s++;
if (!isdigit(*s) && *s != '.')
return(0);
if (isdigit(*s)) {
do {
d1++;
s++;
} while (isdigit(*s));
}
if(d1 >= MAXEXPON)
return(0); /* too many digits to convert */
if (*s == '.') {
point++;
s++;
}
if (isdigit(*s)) {
d2++;
do {
s++;
} while (isdigit(*s));
}
if (!(d1 || point && d2))
return(0);
if (*s == 'e' || *s == 'E') {
s++;
if (*s == '+' || *s == '-')
s++;
if (!isdigit(*s))
return(0);
es = s;
do {
s++;
} while (isdigit(*s));
if (s - es > 2)
return(0);
else if (s - es == 2 && 10 * (*es-'0') + *(es+1)-'0' >= MAXEXPON)
return(0);
}
while (*s == ' ' || *s == '\t' || *s == '\n')
s++;
if (*s == '\0')
return(1);
else
return(0);
}
/*
isnumber(s) char *s; {return(0);}
*/

100
bin/awk/main.c Normal file
View File

@@ -0,0 +1,100 @@
#ifndef lint
static char sccsid[] = "@(#)main.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "stdio.h"
#include "ctype.h"
#include "awk.def"
#include "awk.h"
#define TOLOWER(c) (isupper(c) ? tolower(c) : c) /* ugh!!! */
int dbg = 0;
int svflg = 0;
int rstflg = 0;
int svargc;
char **svargv, **xargv;
extern FILE *yyin; /* lex input file */
char *lexprog; /* points to program argument if it exists */
extern errorflag; /* non-zero if any syntax errors; set by yyerror */
int filefd, symnum, ansfd;
char *filelist;
extern int maxsym, errno;
main(argc, argv) int argc; char *argv[]; {
if (argc == 1)
error(FATAL, "Usage: awk [-f source] [-Fc] ['cmds'] [variable=value ...] [file ...]");
syminit();
while (argc > 1) {
argc--;
argv++;
/* this nonsense is because gcos argument handling */
/* folds -F into -f. accordingly, one checks the next
/* character after f to see if it's -f file or -Fx.
*/
if (argv[0][0] == '-' && TOLOWER(argv[0][1]) == 'f' && argv[0][2] == '\0') {
if (argc <= 1)
error(FATAL, "no argument for -f");
yyin = (strcmp(argv[1], "-") == 0) ? stdin : fopen(argv[1], "r");
if (yyin == NULL)
error(FATAL, "can't open %s", argv[1]);
argc--;
argv++;
break;
} else if (argv[0][0] == '-' && TOLOWER(argv[0][1]) == 'f') { /* set field sep */
if (argv[0][2] == 't') /* special case for tab */
**FS = '\t';
else
**FS = argv[0][2];
continue;
} else if (argv[0][0] != '-') {
dprintf("cmds=|%s|\n", argv[0], NULL, NULL);
yyin = NULL;
lexprog = argv[0];
argv[0] = argv[-1]; /* need this space */
break;
} else if (strcmp("-d", argv[0])==0) {
dbg = 1;
}
else if(strcmp("-S", argv[0]) == 0) {
svflg = 1;
}
else if(strncmp("-R", argv[0], 2) == 0) {
if(thaw(argv[0] + 2) == 0)
rstflg = 1;
else {
fprintf(stderr, "not restored\n");
exit(1);
}
}
}
if (argc <= 1) {
argv[0][0] = '-';
argv[0][1] = '\0';
argc++;
argv--;
}
svargc = --argc;
svargv = ++argv;
dprintf("svargc=%d svargv[0]=%s\n", svargc, svargv[0], NULL);
*FILENAME = *svargv; /* initial file name */
if(rstflg == 0)
yyparse();
dprintf("errorflag=%d\n", errorflag, NULL, NULL);
if (errorflag)
exit(errorflag);
if(svflg) {
svflg = 0;
if(freeze("awk.out") != 0)
fprintf(stderr, "not saved\n");
exit(0);
}
run(winner);
exit(errorflag);
/* NOTREACHED */
}
yywrap()
{
return(1);
}

96
bin/awk/makeprctab.c Normal file
View File

@@ -0,0 +1,96 @@
#ifndef lint
static char sccsid[] = "@(#)makeprctab.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "awk.h"
#define NULL 0
struct xx
{ int token;
char *name;
char *pname;
} proc[] = {
{ PROGRAM, "program", NULL},
{ BOR, "boolop", " || "},
{ AND, "boolop", " && "},
{ NOT, "boolop", " !"},
{ NE, "relop", " != "},
{ EQ, "relop", " == "},
{ LE, "relop", " <= "},
{ LT, "relop", " < "},
{ GE, "relop", " >= "},
{ GT, "relop", " > "},
{ ARRAY, "array", NULL},
{ INDIRECT, "indirect", "$("},
{ SUBSTR, "substr", "substr"},
{ INDEX, "sindex", "sindex"},
{ SPRINTF, "asprintf", "sprintf "},
{ ADD, "arith", " + "},
{ MINUS, "arith", " - "},
{ MULT, "arith", " * "},
{ DIVIDE, "arith", " / "},
{ MOD, "arith", " % "},
{ UMINUS, "arith", " -"},
{ PREINCR, "incrdecr", "++"},
{ POSTINCR, "incrdecr", "++"},
{ PREDECR, "incrdecr", "--"},
{ POSTDECR, "incrdecr", "--"},
{ CAT, "cat", " "},
{ PASTAT, "pastat", NULL},
{ PASTAT2, "dopa2", NULL},
{ MATCH, "matchop", " ~ "},
{ NOTMATCH, "matchop", " !~ "},
{ PRINTF, "aprintf", "printf"},
{ PRINT, "print", "print"},
{ SPLIT, "split", "split"},
{ ASSIGN, "assign", " = "},
{ ADDEQ, "assign", " += "},
{ SUBEQ, "assign", " -= "},
{ MULTEQ, "assign", " *= "},
{ DIVEQ, "assign", " /= "},
{ MODEQ, "assign", " %= "},
{ IF, "ifstat", "if("},
{ WHILE, "whilestat", "while("},
{ FOR, "forstat", "for("},
{ IN, "instat", "instat"},
{ NEXT, "jump", "next"},
{ EXIT, "jump", "exit"},
{ BREAK, "jump", "break"},
{ CONTINUE, "jump", "continue"},
{ FNCN, "fncn", "fncn"},
{ GETLINE, "getline", "getline"},
{ 0, ""},
};
#define SIZE LASTTOKEN - FIRSTTOKEN
char *table[SIZE];
char *names[SIZE];
main()
{
struct xx *p;
int i;
printf("#include \"awk.def\"\n");
printf("CELL *nullproc();\n");
for (i = SIZE; --i >= 0; )
names[i] = "";
for (p=proc; p->token!=0; p++)
if (p==proc || strcmp(p->name, (p-1)->name))
printf("extern CELL *%s();\n",p->name);
for (p=proc; p->token!=0; p++)
table[p->token-FIRSTTOKEN] = p->name;
printf("CELL *(*proctab[%d])() = {\n", SIZE);
for (i=0; i<SIZE; i++)
if (table[i]==0)
printf("/*%s*/\tnullproc,\n", tokname(i+FIRSTTOKEN));
else
printf("/*%s*/\t%s,\n",tokname(i+FIRSTTOKEN),table[i]);
printf("};\n");
printf("char *printname[%d] = {\n", SIZE);
for (p=proc; p->token!=0; p++)
names[p->token-FIRSTTOKEN] = p->pname;
for (i=0; i<SIZE; i++)
printf("/*%s*/\t\"%s\",\n",tokname(i+FIRSTTOKEN),names[i]);
printf("};\n");
exit(0);
/* NOTREACHED */
}

169
bin/awk/parse.c Normal file
View File

@@ -0,0 +1,169 @@
#ifndef lint
static char sccsid[] = "@(#)parse.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "awk.def"
#include "awk.h"
#include "stdio.h"
NODE *nodealloc(n)
{
register NODE *x;
x = (NODE *) malloc(sizeof(NODE) + (n-1)*sizeof(NODE *));
if (x == NULL)
error(FATAL, "out of space in nodealloc");
return(x);
}
NODE *exptostat(a) NODE *a;
{
a->ntype = NSTAT;
return(a);
}
NODE *node0(a)
{
register NODE *x;
x = nodealloc(0);
x->nnext = NULL;
x->nobj = a;
return(x);
}
NODE *node1(a,b) NODE *b;
{
register NODE *x;
x = nodealloc(1);
x->nnext = NULL;
x->nobj = a;
x->narg[0]=b;
return(x);
}
NODE *node2(a,b,c) NODE *b, *c;
{
register NODE *x;
x = nodealloc(2);
x->nnext = NULL;
x->nobj = a;
x->narg[0] = b;
x->narg[1] = c;
return(x);
}
NODE *node3(a,b,c,d) NODE *b, *c, *d;
{
register NODE *x;
x = nodealloc(3);
x->nnext = NULL;
x->nobj = a;
x->narg[0] = b;
x->narg[1] = c;
x->narg[2] = d;
return(x);
}
NODE *node4(a,b,c,d,e) NODE *b, *c, *d, *e;
{
register NODE *x;
x = nodealloc(4);
x->nnext = NULL;
x->nobj = a;
x->narg[0] = b;
x->narg[1] = c;
x->narg[2] = d;
x->narg[3] = e;
return(x);
}
NODE *stat3(a,b,c,d) NODE *b, *c, *d;
{
register NODE *x;
x = node3(a,b,c,d);
x->ntype = NSTAT;
return(x);
}
NODE *op2(a,b,c) NODE *b, *c;
{
register NODE *x;
x = node2(a,b,c);
x->ntype = NEXPR;
return(x);
}
NODE *op1(a,b) NODE *b;
{
register NODE *x;
x = node1(a,b);
x->ntype = NEXPR;
return(x);
}
NODE *stat1(a,b) NODE *b;
{
register NODE *x;
x = node1(a,b);
x->ntype = NSTAT;
return(x);
}
NODE *op3(a,b,c,d) NODE *b, *c, *d;
{
register NODE *x;
x = node3(a,b,c,d);
x->ntype = NEXPR;
return(x);
}
NODE *stat2(a,b,c) NODE *b, *c;
{
register NODE *x;
x = node2(a,b,c);
x->ntype = NSTAT;
return(x);
}
NODE *stat4(a,b,c,d,e) NODE *b, *c, *d, *e;
{
register NODE *x;
x = node4(a,b,c,d,e);
x->ntype = NSTAT;
return(x);
}
NODE *valtonode(a, b) CELL *a;
{
register NODE *x;
x = node0(a);
x->ntype = NVALUE;
x->subtype = b;
return(x);
}
NODE *pa2stat(a,b,c) NODE *a, *b, *c;
{
register NODE *x;
x = node4(PASTAT2, a, b, c, (NODE *) paircnt);
paircnt++;
x->ntype = NSTAT;
return(x);
}
NODE *linkum(a,b) NODE *a, *b;
{
register NODE *c;
if(a == NULL) return(b);
else if(b == NULL) return(a);
for (c = a; c->nnext != NULL; c=c->nnext)
;
c->nnext = b;
return(a);
}
NODE *genprint()
{
register NODE *x;
x = stat2(PRINT,valtonode(lookup("$record", symtab, 0), CFLD), NULL);
return(x);
}

968
bin/awk/run.c Normal file
View File

@@ -0,0 +1,968 @@
#ifndef lint
static char sccsid[] = "@(#)run.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#define DEBUG
#define tempfree(a) {if(istemp(a)) {xfree(a->sval) ;a->tval = 0;}}
#include "awk.def"
#include "math.h"
#include "awk.h"
#include "stdio.h"
#define RECSIZE BUFSIZ
#define FILENUM 10
struct
{
FILE *fp;
int type;
char *fname;
} files[FILENUM];
FILE *popen();
extern CELL *execute(), *nodetoobj(), *fieldel(), *dopa2(), *gettemp();
extern char *malloc(), *realloc();
#define PA2NUM 29
int pairstack[PA2NUM], paircnt;
NODE *winner = NULL;
#define MAXTMP 20
CELL tmps[MAXTMP];
static CELL truecell ={ OBOOL, BTRUE, 0, 0, 0.0, NUM, 0 };
CELL *true = &truecell;
static CELL falsecell ={ OBOOL, BFALSE, 0, 0, 0.0, NUM, 0 };
CELL *false = &falsecell;
static CELL breakcell ={ OJUMP, JBREAK, 0, 0, 0.0, NUM, 0 };
CELL *jbreak = &breakcell;
static CELL contcell ={ OJUMP, JCONT, 0, 0, 0.0, NUM, 0 };
CELL *jcont = &contcell;
static CELL nextcell ={ OJUMP, JNEXT, 0, 0, 0.0, NUM, 0 };
CELL *jnext = &nextcell;
static CELL exitcell ={ OJUMP, JEXIT, 0, 0, 0.0, NUM, 0 };
CELL *jexit = &exitcell;
static CELL tempcell ={ OCELL, CTEMP, 0, 0, 0.0, NUM, 0 };
run(a) NODE *a;
{
register int i;
execute(a);
/* Wait for children to complete if output to a pipe. */
for (i=0; i<FILENUM; i++)
if (files[i].fp && files[i].type == '|')
pclose(files[i].fp);
}
CELL *execute(u) NODE *u;
{
register CELL *(*proc)();
register CELL *x;
register NODE *a;
extern char *printname[];
if (u == NULL)
return(true);
for (a = u; ; a = a->nnext) {
if (cantexec(a))
return(nodetoobj(a));
if (notlegal(a->nobj))
error(FATAL, "illegal statement %o", a);
proc = proctab[a->nobj-FIRSTTOKEN];
x = (*proc)(a->narg, a->nobj);
if (isfld(x))
fldbld();
if (isexpr(a))
return(x);
/* a statement, goto next statement */
if (isjump(x))
return(x);
if (a->nnext == (NODE *)NULL)
return(x);
tempfree(x);
}
}
CELL *program(a, n) register NODE **a;
{
register CELL *x;
if (a[0] != NULL) {
x = execute(a[0]);
if (isexit(x))
return(true);
if (isjump(x))
error(FATAL, "unexpected break, continue or next");
tempfree(x);
}
while (getrec()) {
x = execute(a[1]);
if (isexit(x)) {
tempfree(x);
break;
}
tempfree(x);
}
if (a[2] != NULL) {
x = execute(a[2]);
if (isbreak(x) || isnext(x) || iscont(x))
error(FATAL, "unexpected break, continue or next");
tempfree(x);
}
return(true);
}
CELL *getline()
{
register CELL *x;
x = gettemp();
setfval(x, (awkfloat) getrec());
return(x);
}
CELL *array(a,n) register NODE **a;
{
register CELL *x, *y;
extern CELL *arrayel();
x = execute(a[1]);
y = arrayel(a[0], x);
tempfree(x);
return(y);
}
CELL *arrayel(a, b) NODE *a; CELL *b;
{
register char *s;
register CELL *x;
register int i;
register CELL *y;
s = getsval(b);
x = (CELL *) a;
if (!(x->tval&ARR)) {
xfree(x->sval);
x->tval &= ~STR;
x->tval |= ARR;
x->sval = (char *) makesymtab();
}
y = setsymtab(s, tostring(""), 0.0, STR|NUM, x->sval);
y->ctype = OCELL;
y->csub = CVAR;
return(y);
}
CELL *matchop(a,n) NODE **a;
{
register CELL *x;
register char *s;
register int i;
x = execute(a[0]);
s = getsval(x);
tempfree(x);
i = match(a[1], s);
if (n == MATCH && i == 1 || n == NOTMATCH && i == 0)
return(true);
else
return(false);
}
CELL *boolop(a,n) NODE **a;
{
register CELL *x, *y;
register int i;
x = execute(a[0]);
i = istrue(x);
tempfree(x);
switch (n) {
case BOR:
if (i) return(true);
y = execute(a[1]);
i = istrue(y);
tempfree(y);
if (i) return(true);
else return(false);
case AND:
if ( !i ) return(false);
y = execute(a[1]);
i = istrue(y);
tempfree(y);
if (i) return(true);
else return(false);
case NOT:
if (i) return(false);
else return(true);
default:
error(FATAL, "unknown boolean operator %d", n);
}
/*NOTREACHED*/
}
CELL *relop(a,n) NODE **a;
{
register int i;
register CELL *x, *y;
awkfloat j;
x = execute(a[0]);
y = execute(a[1]);
if (x->tval&NUM && y->tval&NUM) {
j = x->fval - y->fval;
i = j<0? -1: (j>0? 1: 0);
} else {
i = strcmp(getsval(x), getsval(y));
}
tempfree(x);
tempfree(y);
switch (n) {
case LT: if (i<0) return(true);
else return(false);
case LE: if (i<=0) return(true);
else return(false);
case NE: if (i!=0) return(true);
else return(false);
case EQ: if (i == 0) return(true);
else return(false);
case GE: if (i>=0) return(true);
else return(false);
case GT: if (i>0) return(true);
else return(false);
default:
error(FATAL, "unknown relational operator %d", n);
}
/*NOTREACHED*/
}
CELL *gettemp()
{
register int i;
register CELL *x;
for (i=0; i<MAXTMP; i++)
if (tmps[i].tval == 0)
break;
if (i == MAXTMP)
error(FATAL, "out of temporaries in gettemp");
tmps[i] = tempcell;
x = &tmps[i];
return(x);
}
CELL *indirect(a,n) NODE **a;
{
register CELL *x;
register int m;
CELL *fieldadr();
x = execute(a[0]);
m = getfval(x);
tempfree(x);
x = fieldadr(m);
x->ctype = OCELL;
x->csub = CFLD;
return(x);
}
CELL *substr(a, nnn) NODE **a;
{
register int k, m, n;
register char *s, temp;
register CELL *x;
x = execute(a[0]);
s = getsval(x);
k = strlen(s) + 1;
tempfree(x);
if (k <= 1) {
x = gettemp();
setsval(x, "");
return(x);
}
x = execute(a[1]);
m = getfval(x);
if (m <= 0)
m = 1;
else if (m > k)
m = k;
tempfree(x);
if (a[2] != 0) {
x = execute(a[2]);
n = getfval(x);
tempfree(x);
}
else
n = k - 1;
if (n < 0)
n = 0;
else if (n > k - m)
n = k - m;
dprintf("substr: m=%d, n=%d, s=%s\n", m, n, s);
x = gettemp();
temp = s[n+m-1]; /* with thanks to John Linderman */
s[n+m-1] = '\0';
setsval(x, s + m - 1);
s[n+m-1] = temp;
return(x);
}
CELL *sindex(a, nnn) NODE **a;
{
register CELL *x;
register char *s1, *s2, *p1, *p2, *q;
x = execute(a[0]);
s1 = getsval(x);
tempfree(x);
x = execute(a[1]);
s2 = getsval(x);
tempfree(x);
x = gettemp();
for (p1 = s1; *p1 != '\0'; p1++) {
for (q=p1, p2=s2; *p2 != '\0' && *q == *p2; q++, p2++)
;
if (*p2 == '\0') {
setfval(x, (awkfloat) (p1 - s1 + 1)); /* origin 1 */
return(x);
}
}
setfval(x, 0.0);
return(x);
}
char *format(s,a) char *s; NODE *a;
{
register char *buf, *p, fmt[200], *t, *os, *ep, tbuf[300], *str;
register CELL *x;
int flag = 0;
awkfloat xf;
os = s;
p = buf = (char *)malloc(RECSIZE);
if (p == NULL)
error(FATAL, "out of space in format");
ep = p + RECSIZE;
while (*s) {
if (*s != '%') {
*p++ = *s++;
continue;
}
if (*(s+1) == '%') {
*p++ = '%';
s += 2;
continue;
}
for (t=fmt; (*t++ = *s) != '\0'; s++)
if (*s >= 'a' && *s <= 'z' && *s != 'l')
break;
*t = '\0';
if (t >= fmt + sizeof(fmt))
error(FATAL, "format item %.20s... too long", os);
switch (*s) {
case 'f': case 'e': case 'g':
flag = 1;
break;
case 'd':
flag = 2;
if(*(s-1) == 'l') break;
*(t-1) = 'l';
*t = 'd';
*++t = '\0';
break;
case 'o': case 'x':
flag = *(s-1) == 'l' ? 2 : 3;
break;
case 'c':
flag = 3;
break;
case 's':
flag = 4;
break;
default:
flag = 0;
break;
}
if (flag == 0) {
sprintf(p, "%s", fmt);
p += strlen(p);
continue;
}
if (a == NULL)
error(FATAL, "not enough arguments in printf(%s)", os);
x = execute(a);
a = a->nnext;
/*
* Get the string to check length; %s is the usual problem;
* other conversions can cause overrun if they occur when
* the buffer is almost filled.
*/
if (flag == 4) { /* watch out for converting to numbers! */
str = getsval(x);
}
else {
xf = getfval(x);
if (flag == 1) sprintf(tbuf, fmt, xf);
else if (flag == 2) sprintf(tbuf, fmt, (long)xf);
else if (flag == 3) sprintf(tbuf, fmt, (int)xf);
if (strlen(tbuf) > sizeof(tbuf))
error(FATAL, "formatted item %s... too long",
tbuf);
str = tbuf;
}
/*
* If string overruns the buffer, reallocate;
* consider length of format string
*/
if (ep < p + strlen(str) + strlen(s)) {
int newlen, oldlen;
oldlen = p - buf;
/* Add RECSIZE for additional space */
newlen = oldlen + strlen(str) + RECSIZE;
buf = realloc(buf, (unsigned) newlen);
if (buf == NULL)
error(FATAL, "out of format space");
p = buf + oldlen;
ep = buf + newlen;
}
/* Transfer string to buffer */
if (flag == 4)
sprintf(p, fmt, str);
else
strcpy(p, str);
tempfree(x);
p += strlen(p);
if (p > ep)
error(FATAL, "formatted string too long");
s++;
}
*p = '\0';
return(buf);
}
CELL *asprintf(a,n) NODE **a;
{
register CELL *x;
register NODE *y;
register char *s;
y = a[0]->nnext;
x = execute(a[0]);
s = format(getsval(x), y);
tempfree(x);
x = gettemp();
x->sval = s;
x->tval = STR;
return(x);
}
CELL *arith(a,n) NODE **a;
{
awkfloat i, j;
register CELL *x, *y, *z;
x = execute(a[0]);
i = getfval(x);
tempfree(x);
if (n != UMINUS) {
y = execute(a[1]);
j = getfval(y);
tempfree(y);
}
z = gettemp();
switch (n) {
case ADD:
i += j;
break;
case MINUS:
i -= j;
break;
case MULT:
i *= j;
break;
case DIVIDE:
if (j == 0)
error(FATAL, "division by zero");
i /= j;
break;
case MOD:
if (j == 0)
error(FATAL, "division by zero");
i = i - j*(long)(i/j);
break;
case UMINUS:
i = -i;
break;
default:
error(FATAL, "illegal arithmetic operator %d", n);
}
setfval(z, i);
return(z);
}
CELL *incrdecr(a, n) NODE **a;
{
register CELL *x, *z;
register int k;
awkfloat xf;
x = execute(a[0]);
xf = getfval(x);
k = (n == PREINCR || n == POSTINCR) ? 1 : -1;
if (n == PREINCR || n == PREDECR) {
setfval(x, xf + k);
return(x);
}
z = gettemp();
setfval(z, xf);
setfval(x, xf + k);
tempfree(x);
return(z);
}
CELL *assign(a,n) NODE **a;
{
register CELL *x, *y;
awkfloat xf, yf;
x = execute(a[0]);
y = execute(a[1]);
if (n == ASSIGN) { /* ordinary assignment */
if ((y->tval & (STR|NUM)) == (STR|NUM)) {
setsval(x, y->sval);
x->fval = y->fval;
x->tval |= NUM;
}
else if (y->tval & STR)
setsval(x, y->sval);
else if (y->tval & NUM)
setfval(x, y->fval);
tempfree(y);
return(x);
}
xf = getfval(x);
yf = getfval(y);
switch (n) {
case ADDEQ:
xf += yf;
break;
case SUBEQ:
xf -= yf;
break;
case MULTEQ:
xf *= yf;
break;
case DIVEQ:
if (yf == 0)
error(FATAL, "division by zero");
xf /= yf;
break;
case MODEQ:
if (yf == 0)
error(FATAL, "division by zero");
xf = xf - yf*(long)(xf/yf);
break;
default:
error(FATAL, "illegal assignment operator %d", n);
break;
}
tempfree(y);
setfval(x, xf);
return(x);
}
CELL *cat(a,q) NODE **a;
{
register CELL *x, *y, *z;
register int n1, n2;
register char *s;
x = execute(a[0]);
y = execute(a[1]);
getsval(x);
getsval(y);
n1 = strlen(x->sval);
n2 = strlen(y->sval);
if ((s = (char *) malloc(n1 + n2 + 1)) == NULL)
error(FATAL, "out of space in cat");
strcpy(s, x->sval);
strcpy(s+n1, y->sval);
tempfree(y);
z = gettemp();
z->sval = s;
z->tval = STR;
tempfree(x);
return(z);
}
CELL *pastat(a,n) NODE **a;
{
register CELL *x;
if (a[0] == 0)
x = true;
else
x = execute(a[0]);
if (istrue(x)) {
tempfree(x);
x = execute(a[1]);
}
return(x);
}
CELL *dopa2(a,n) NODE **a;
{
register CELL *x;
register int pair;
pair = (int) a[3];
if (pairstack[pair] == 0) {
x = execute(a[0]);
if (istrue(x))
pairstack[pair] = 1;
tempfree(x);
}
if (pairstack[pair] == 1) {
x = execute(a[1]);
if (istrue(x))
pairstack[pair] = 0;
tempfree(x);
x = execute(a[2]);
return(x);
}
return(false);
}
CELL *aprintf(a,n) NODE **a;
{
register CELL *x;
x = asprintf(a,n);
if (a[1] == NULL) {
printf("%s", x->sval);
tempfree(x);
return(true);
}
redirprint(x->sval, (int)a[1], a[2]);
return(x);
}
static int ctest[0200];
CELL *split(a,nnn) NODE **a;
{
register CELL *x;
register CELL *ap;
register char *s, *p;
char *t, temp, num[5];
register int sep;
int n, flag;
x = execute(a[0]);
s = getsval(x);
tempfree(x);
if (a[2] == 0)
sep = **FS;
else {
x = execute(a[2]);
sep = getsval(x)[0];
tempfree(x);
}
ap = (CELL *) a[1];
freesymtab(ap);
dprintf("split: s=|%s|, a=%s, sep=|%c|\n", s, ap->nval, sep);
ap->tval &= ~STR;
ap->tval |= ARR;
ap->sval = (char *) makesymtab();
n = 0;
if (sep == ' ')
for (n = 0; ; ) {
while (*s == ' ' || *s == '\t' || *s == '\n')
s++;
if (*s == 0)
break;
n++;
t = s;
ctest[' '] = ctest['\t'] = ctest['\n'] = ctest['\0'] =1;
do
s++;
/*while (*s!=' ' && *s!='\t' && *s!='\n' && *s!='\0');*/
while(!ctest[*s]);
ctest[' '] = ctest['\t'] = ctest['\n'] = ctest['\0'] =0;
temp = *s;
*s = '\0';
sprintf(num, "%d", n);
if (isnumber(t))
setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval);
else
setsymtab(num, tostring(t), 0.0, STR, ap->sval);
*s = temp;
if (*s != 0)
s++;
}
else if (*s != 0)
for (;;) {
n++;
t = s;
ctest[sep] = ctest['\n'] = ctest['\0'] = 1;
while(!ctest[*s])
/*while (*s != sep && *s != '\n' && *s != '\0')*/
s++;
ctest[sep] = ctest['\n'] = ctest['\0'] = 0;
temp = *s;
*s = '\0';
sprintf(num, "%d", n);
if (isnumber(t))
setsymtab(num, tostring(t), atof(t), STR|NUM, ap->sval);
else
setsymtab(num, tostring(t), 0.0, STR, ap->sval);
*s = temp;
if (*s++ == 0)
break;
}
x = gettemp();
x->tval = NUM;
x->fval = n;
return(x);
}
CELL *ifstat(a,n) NODE **a;
{
register CELL *x;
x = execute(a[0]);
if (istrue(x)) {
tempfree(x);
x = execute(a[1]);
}
else if (a[2] != 0) {
tempfree(x);
x = execute(a[2]);
}
return(x);
}
CELL *whilestat(a,n) NODE **a;
{
register CELL *x;
for (;;) {
x = execute(a[0]);
if (!istrue(x)) return(x);
tempfree(x);
x = execute(a[1]);
if (isbreak(x)) {
x = true;
return(x);
}
if (isnext(x) || isexit(x))
return(x);
tempfree(x);
}
/*NOTREACHED*/
}
CELL *forstat(a,n) NODE **a;
{
register CELL *x;
register CELL *z;
z = execute(a[0]);
tempfree(z);
for (;;) {
if (a[1]!=0) {
x = execute(a[1]);
if (!istrue(x)) return(x);
else tempfree(x);
}
x = execute(a[3]);
if (isbreak(x)) { /* turn off break */
x = true;
return(x);
}
if (isnext(x) || isexit(x))
return(x);
tempfree(x);
z = execute(a[2]);
tempfree(z);
}
}
CELL *instat(a, n) NODE **a;
{
register CELL *vp, *arrayp, *cp, **tp;
register CELL *x;
int i;
vp = (CELL *) a[0];
arrayp = (CELL *) a[1];
if (!(arrayp->tval & ARR))
error(FATAL, "%s is not an array", arrayp->nval);
tp = (CELL **) arrayp->sval;
for (i = 0; i < MAXSYM; i++) { /* this routine knows too much */
for (cp = tp[i]; cp != NULL; cp = cp->nextval) {
setsval(vp, cp->nval);
x = execute(a[2]);
if (isbreak(x)) {
x = true;
return(x);
}
if (isnext(x) || isexit(x))
return(x);
tempfree(x);
}
}
return (true);
}
CELL *jump(a, n) NODE **a;
{
register CELL *y;
switch (n) {
case EXIT:
if (a[0] != 0) {
y = execute(a[0]);
errorflag = getfval(y);
}
return(jexit);
case NEXT:
return(jnext);
case BREAK:
return(jbreak);
case CONTINUE:
return(jcont);
default:
error(FATAL, "illegal jump type %d", n);
}
/*NOTREACHED*/
}
CELL *fncn(a,n) NODE **a;
{
register CELL *x;
awkfloat u;
register int t;
t = (int) a[0];
x = execute(a[1]);
if (t == FLENGTH)
u = (awkfloat) strlen(getsval(x));
else if (t == FLOG)
u = log(getfval(x));
else if (t == FINT)
u = (awkfloat) (long) getfval(x);
else if (t == FEXP)
u = exp(getfval(x));
else if (t == FSQRT)
u = sqrt(getfval(x));
else
error(FATAL, "illegal function type %d", t);
tempfree(x);
x = gettemp();
setfval(x, u);
return(x);
}
CELL *print(a,n) NODE **a;
{
register NODE *x;
register CELL *y;
char s[RECSIZE], *str, *bp, *ep;
s[0] = '\0';
bp = s;
ep = s + RECSIZE;
for (x=a[0]; x!=NULL; x=x->nnext) {
y = execute(x);
str = getsval(y);
/* allocate larger buffer if needed */
if (ep < bp + strlen(bp) + strlen(str)) {
int newlen;
char *oldbp;
newlen = strlen(bp) + strlen(str) + 1 + 1;
oldbp = bp;
bp = malloc((unsigned) newlen);
if (bp == NULL)
error(FATAL, "out of space in print");
ep = bp + newlen;
strcpy(bp, oldbp);
if (oldbp != s)
free(oldbp);
}
strcat(bp, str);
tempfree(y);
if (x->nnext == NULL)
strcat(bp, *ORS);
else
strcat(bp, *OFS);
}
if (a[1] == 0) {
printf("%s", bp);
if (bp != s)
free(bp);
return(true);
}
redirprint(bp, (int)a[1], a[2]);
if (bp != s)
free(bp);
return(false);
}
CELL *nullproc() {}
CELL *nodetoobj(a) NODE *a;
{
register CELL *x;
x= (CELL *) a->nobj;
x->ctype = OCELL;
x->csub = a->subtype;
if (isfld(x))
fldbld();
return(x);
}
redirprint(s, a, b) char *s; NODE *b;
{
register int i;
register CELL *x;
x = execute(b);
getsval(x);
for (i=0; i<FILENUM; i++)
if (files[i].fp != 0 && strcmp(x->sval, files[i].fname) == 0)
goto doit;
for (i=0; i<FILENUM; i++)
if (files[i].fp == 0)
break;
if (i >= FILENUM)
error(FATAL, "too many output files %d", i);
if (a == '|') /* a pipe! */
files[i].fp = popen(x->sval, "w");
else if (a == APPEND)
files[i].fp = fopen(x->sval, "a");
else if (a == GT)
files[i].fp = fopen(x->sval, "w");
else
error(FATAL, "illegal redirection near line %d", lineno);
if (files[i].fp == NULL)
error(FATAL, "can't open file %s", x->sval);
files[i].fname = tostring(x->sval);
files[i].type = a;
doit:
fprintf(files[i].fp, "%s", s);
#ifndef gcos
fflush(files[i].fp); /* in case someone is waiting for the output */
#endif
tempfree(x);
}

26
bin/awk/token.c Normal file
View File

@@ -0,0 +1,26 @@
#ifndef lint
static char sccsid[] = "@(#)token.c 1.1 92/07/30 SMI; from UCB 4.1 82/12/24";
#endif
#include "awk.h"
struct tok
{ char *tnm;
int yval;
} tok[] = {
#include "tokendefs"
};
ptoken(n)
{
if(n<128) printf("lex: %c\n",n);
else if(n<=256) printf("lex:? %o\n",n);
else if(n<LASTTOKEN) printf("lex: %s\n",tok[n-257].tnm);
else printf("lex:? %o\n",n);
return;
}
char *tokname(n)
{
if (n<=256 || n >= LASTTOKEN)
n = 257;
return(tok[n-257].tnm);
}

8
bin/awk/tokenscript Normal file
View File

@@ -0,0 +1,8 @@
e y.tab.h
g:@(#)tokenscript 1.1 92/07/30 SMI; from UCB 4.2 beta:s///
1,$s/# *define *//
1,$s/^/"/
1,$s/ /", /
1,$s/$/,/
w tokendefs
q

277
bin/awk/tran.c Normal file
View File

@@ -0,0 +1,277 @@
#ifndef lint
static char sccsid[] = "@(#)tran.c 1.1 92/07/30 SMI"; /* from S5R2 */
#endif
#include "stdio.h"
#include "awk.def"
#include "awk.h"
CELL *symtab[MAXSYM]; /* symbol table pointers */
char **FS; /* initial field sep */
char **RS; /* initial record sep */
char **OFS; /* output field sep */
char **ORS; /* output record sep */
char **OFMT; /*output format for numbers*/
awkfloat *NF; /* number of fields in current record */
awkfloat *NR; /* number of current record */
char **FILENAME; /* current filename argument */
CELL *recloc; /* location of record */
CELL *nrloc; /* NR */
CELL *nfloc; /* NF */
syminit()
{
setsymtab("0", tostring("0"), 0.0, NUM|STR|CON|FLD, symtab);
/* this one is used for if(x)... tests: */
setsymtab("$zero&null", tostring(""), 0.0, NUM|STR|CON|FLD, symtab);
recloc = setsymtab("$record", record, 0.0, STR|FLD, symtab);
dprintf("recloc %o lookup %o\n", recloc, lookup("$record", symtab, 0), NULL);
FS = &setsymtab("FS", tostring(" "), 0.0, STR|FLD, symtab)->sval;
RS = &setsymtab("RS", tostring("\n"), 0.0, STR|FLD, symtab)->sval;
OFS = &setsymtab("OFS", tostring(" "), 0.0, STR|FLD, symtab)->sval;
ORS = &setsymtab("ORS", tostring("\n"), 0.0, STR|FLD, symtab)->sval;
OFMT = &setsymtab("OFMT", tostring("%.6g"), 0.0, STR|FLD, symtab)->sval;
FILENAME = &setsymtab("FILENAME", NULL, 0.0, STR|FLD, symtab)->sval;
nfloc = setsymtab("NF", NULL, 0.0, NUM, symtab);
NF = &nfloc->fval;
nrloc = setsymtab("NR", NULL, 0.0, NUM, symtab);
NR = &nrloc->fval;
}
CELL **makesymtab()
{
int i;
CELL **cp;
cp = (CELL **) malloc(MAXSYM * sizeof(CELL *));
if (cp == NULL)
error(FATAL, "out of space in makesymtab");
for (i = 0; i < MAXSYM; i++)
cp[i] = 0;
return(cp);
}
freesymtab(ap) /* free symbol table */
CELL *ap;
{
CELL *cp, **tp;
int i;
if (!(ap->tval & ARR))
return;
tp = (CELL **) ap->sval;
for (i = 0; i < MAXSYM; i++) {
for (cp = tp[i]; cp != NULL; cp = cp->nextval) {
xfree(cp->nval);
xfree(cp->sval);
free(cp);
}
}
xfree(tp);
}
CELL *setsymtab(n, s, f, t, tab)
char *n, *s;
awkfloat f;
unsigned t;
CELL **tab;
{
register h;
register CELL *p;
CELL *lookup();
if (n != NULL && (p = lookup(n, tab, 0)) != NULL) {
xfree(s);
dprintf("setsymtab found %o: %s", p, p->nval, NULL);
dprintf(" %s %g %o\n", p->sval, p->fval, p->tval);
return(p);
}
p = (CELL *) malloc(sizeof(CELL));
if (p == NULL)
error(FATAL, "symbol table overflow at %s", n);
p->nval = tostring(n);
p->sval = s;
p->fval = f;
p->tval = t;
h = hash(n);
p->nextval = tab[h];
tab[h] = p;
dprintf("setsymtab set %o: %s", p, p->nval, NULL);
dprintf(" %s %g %o\n", p->sval, p->fval, p->tval);
return(p);
}
hash(s) /* form hash value for string s */
register unsigned char *s;
{
register int hashval;
for (hashval = 0; *s != '\0'; )
hashval += *s++;
return(hashval % MAXSYM);
}
CELL *lookup(s, tab, flag) /* look for s in tab, flag must match*/
register char *s;
CELL **tab;
{
register CELL *p;
for (p = tab[hash(s)]; p != NULL; p = p->nextval)
if (strcmp(s, p->nval) == 0 &&
(flag == 0 || flag == p->tval))
return(p); /* found it */
return(NULL); /* not found */
}
awkfloat setfval(vp, f)
register CELL *vp;
awkfloat f;
{
dprintf("setfval: %o %g\n", vp, f, NULL);
/*imb*/
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval,
vp->sval, vp->fval, vp->tval);
/*imb*/
if (vp == recloc)
error(FATAL, "can't set $0");
vp->tval &= ~STR; /* mark string invalid */
vp->tval |= NUM; /* mark number ok */
if ((vp->tval & FLD) && vp->nval == 0) {
/*
* FLD really means that the string value was not
* "malloc"ed and should not be freed. All fields
* have this property, but not all cells with this
* property are fields. However, all cells with
* this property and with a NULL "nval" are fields.
* If we are setting the value of a field, indicate
* that the value of the record has to be recomputed,
* and if it's a higher field than the last one we
* assigned to, remember it for when we clear the
* fields out for the next record.
*/
donerec = 0;
if (vp > maxmfld)
maxmfld = vp;
}
return(vp->fval = f);
}
char *setsval(vp, s)
register CELL *vp;
char *s;
{
dprintf("setsval: %o %s\n", vp, s, NULL);
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval,
vp->sval, vp->fval, vp->tval);
if (vp == recloc)
error(FATAL, "can't set $0");
vp->tval &= ~NUM;
vp->tval |= STR;
if ((vp->tval & FLD) && vp->nval == 0) {
/*
* See comment in "setfval".
*/
donerec = 0;
if (vp > maxmfld)
maxmfld = vp;
}
if (!(vp->tval&FLD))
xfree(vp->sval);
vp->tval &= ~FLD;
return(vp->sval = tostring(s));
}
awkfloat getfval(vp)
register CELL *vp;
{
if (vp->sval == record && donerec == 0)
recbld();
dprintf("getfval: %o", vp, NULL, NULL);
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval,
vp->sval, vp->fval, vp->tval);
if ((vp->tval & NUM) == 0) {
/* the problem is to make non-numeric things */
/* have unlikely numeric variables, so that */
/* $1 == $2 comparisons sort of make sense when */
/* one or the other is numeric */
if (isnumber(vp->sval)) {
vp->fval = atof(vp->sval);
if (!(vp->tval & CON)) /* don't change type of a constant */
vp->tval |= NUM;
}
else
vp->fval = 0.0; /* not a very good idea */
}
dprintf(" %g\n", vp->fval, NULL, NULL);
return(vp->fval);
}
char *getsval(vp)
register CELL *vp;
{
char s[100];
if (vp->sval == record && donerec == 0)
recbld();
dprintf("getsval: %o", vp, NULL, NULL);
if (vp->tval & ARR)
error(FATAL, "illegal reference to array %s", vp->nval);
if ((vp->tval & (NUM | STR)) == 0)
error(FATAL, "funny variable %o: %s %s %g %o", vp, vp->nval,
vp->sval, vp->fval, vp->tval);
if ((vp->tval & STR) == 0) {
if (!(vp->tval&FLD))
xfree(vp->sval);
if ((long)vp->fval==vp->fval)
sprintf(s, "%.20g", vp->fval);
else
sprintf(s, *OFMT, vp->fval);
vp->sval = tostring(s);
vp->tval &= ~FLD;
vp->tval |= STR;
}
dprintf(" %s\n", vp->sval, NULL, NULL);
return(vp->sval);
}
char *tostring(s)
register char *s;
{
register char *p;
p = malloc(strlen(s)+1);
if (p == NULL)
error(FATAL, "out of space in tostring on %s", s);
strcpy(p, s);
return(p);
}
#ifndef yfree
yfree(a) char *a;
{
printf("%o\n", a);
free(a);
}
#endif
#ifdef malloc
#undef malloc
char *ymalloc(u) unsigned u;
{ char *p;
p = malloc(u);
printf("%o %o\n", u, p);
return(p);
}
#endif

3515
bin/bar.c Normal file

File diff suppressed because it is too large Load Diff

806
bin/cc.c Normal file
View File

@@ -0,0 +1,806 @@
#ifndef lint
static char sccsid[] = "@(#)cc.c 1.1 92/07/30 SMI"; /* from UCB 4.7 83/07/01 */
#endif
/*
* cc - front end for C compiler
*/
#include <sys/param.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <sys/dir.h>
#include <strings.h>
extern char * sys_siglist[];
char *cpp = "/lib/cpp";
char *count = "/usr/lib/bb_count";
char *ccom = "/lib/ccom";
char *inline = "/usr/lib/inline";
char *c2 = "/lib/c2";
char *as = "/bin/as";
char *ld = "/bin/ld";
char *libc = "-lc";
char *crt0 = "crt0.o";
char *gcrt0 = "gcrt0.o";
char *mcrt0 = "mcrt0.o";
char tmp0[30]; /* big enough for /tmp/ctm%05.5d */
char *tmp1, *tmp2, *tmp3, *tmp4, *tmp5;
char *outfile;
char *asoutfile;
char *savestr(), *strspl(), *setsuf();
char *getsuf();
int idexit();
char **av, **clist, **llist, **plist;
int cflag, eflag, oflag, pflag, sflag, wflag, Rflag, exflag, proflag;
int aflag;
int gproflag, gflag, Gflag;
int vflag;
int iflag;
int Jflag;
int chlibflag;
extern char *malloc(), *calloc();
#define strequal(s1,s2) (strcmp((s1),(s2))==0)
#ifdef mc68000
/*
* starting in release 3.0, we must figure out what kind of processor
* we are running on, and generate code accordingly. This requires
* some magic routines from libc.a
*/
int is68020(); /* returns 1 if the host is a 68020 */
struct mach_info {
char *optname;
int found;
int isatype;
char *crt1;
};
struct mach_info machopts[] = {
"-m68010", 0, 1, (char*)0, /* use 68010 subset */
"-m68020", 0, 1, (char*)0, /* use 68020 extensions */
(char*)0
};
struct mach_info floatopts[] = {
"-ffpa", 0, 1, "Wcrt1.o", /* sun fpa */
"-f68881", 0, 1, "Mcrt1.o", /* 68881 */
"-fsky", 0, 1, "Scrt1.o", /* sky board */
"-fsoft", 0, 1, "Fcrt1.o", /* software floating point */
"-fswitch", 0, 1, (char*)0, /* switched floating point */
"-fsingle", 0, 0, (char*)0, /* single precision float */
"-fsingle2", 0, 0, (char*)0, /* pass float args as floats */
"-fstore", 0, 0, (char*)0, /* coerce fp regs to storage format */
(char *)0 ,
};
extern char *getenv();
char *FLOAT_OPTION = "FLOAT_OPTION";
struct mach_info *machtype=NULL; /* selected target machine type */
struct mach_info *fptype=NULL; /* selected floating pt machine type */
struct mach_info *default_machtype(); /* default target machine type */
struct mach_info *default_fptype(); /* default floating point machine */
#define M_68010 &machopts[0]
#define M_68020 &machopts[1]
#define F_fpa &floatopts[0]
#define F_68881 &floatopts[1]
#define F_sky &floatopts[2]
#define F_soft &floatopts[3]
#define F_switch &floatopts[4]
#define F_store &floatopts[5]
#define use68010 (machtype == M_68010)
#define use68020 (machtype == M_68020)
#define unsupported(machtype, fptype) \
( machtype == M_68010 && fptype == F_fpa \
|| machtype == M_68020 && fptype == F_sky )
#endif
char *dflag;
int exfail;
char *chpass;
char *npassname;
char *ccname;
int nc, nl, np, nxo, na;
main(argc, argv)
register int argc;
register char **argv;
{
char *t;
char *assource;
char *cppout;
char *cp;
register int i, j, tmpi;
register struct mach_info *mp;
int optfound;
/* ld currently adds upto 5 args; 10 is room to spare */
av = (char **)calloc((unsigned)argc+10, sizeof (char **));
clist = (char **)calloc((unsigned)argc, sizeof (char **));
llist = (char **)calloc((unsigned)argc, sizeof (char **));
plist = (char **)calloc((unsigned)argc, sizeof (char **));
ccname = argv[0];
for (i = 1; i < argc; i++) {
if (*argv[i] == '-') switch (argv[i][1]) {
case 'S':
sflag++;
cflag++;
continue;
case 'o':
if (++i < argc) {
outfile = argv[i];
cp = getsuf(outfile);
if (strequal(cp, "c") || strequal(cp, "o")) {
error("-o would overwrite %s",
outfile);
exit(8);
}
}
continue;
case 'R':
Rflag++;
continue;
case 'O':
/*
* There might be further chars after -O; we just
* pass them on to c2 as an extra argument -- later.
*/
oflag++;
continue;
case 'J':
Jflag++;
continue;
case 'p':
proflag++;
if (argv[i][2] == 'g'){
crt0 = gcrt0;
gproflag++;
} else {
crt0 = mcrt0;
}
continue;
case 'g':
if (argv[i][2] == 'o') {
Gflag++; /* old format for -go */
} else {
gflag++; /* new format for -g */
}
continue;
case 'w':
wflag++;
continue;
case 'E':
exflag++;
case 'P':
pflag++;
plist[np++] = argv[i];
case 'c':
cflag++;
continue;
case 'D':
case 'I':
case 'U':
case 'C':
plist[np++] = argv[i];
continue;
case 't':
if (chpass)
error("-t overwrites earlier option", 0);
chpass = argv[i]+2;
if (chpass[0]==0)
chpass = "012pialc";
continue;
case 'f':
#ifdef mc68000
/*
* floating point option switches
*/
optfound = 0;
for (mp = floatopts; mp->optname; mp++) {
if (!strcmp(argv[i], mp->optname)){
if (mp->isatype) {
if (fptype != NULL && fptype != mp) {
error("%s overwrites earlier option",
mp->optname);
}
fptype = mp;
} else {
mp->found = 1;
}
optfound = 1;
break;
}
}
if (!optfound) {
if (argv[i][2] == '\0') {
fprintf(stderr,
"%s: warning: -f option is obsolete\n",
ccname);
} else {
fprintf(stderr,
"%s: warning: %s option not recognized\n",
ccname, argv[i]);
}
}
continue;
#else !mc68000
fprintf(stderr,
"%s: warning: -f option is obsolete\n",
ccname);
continue;
#endif !mc68000
#ifdef mc68000
case 'm':
optfound = 0;
for (mp = machopts; mp->optname; mp++) {
if (!strcmp(argv[i], mp->optname)) {
if (mp->isatype) {
if (machtype != NULL && machtype != mp) {
error("%s overwrites earlier option",
mp->optname);
}
machtype = mp;
} else {
mp->found = 1;
}
optfound = 1;
break;
}
}
if (!optfound) {
fprintf(stderr,
"%s: warning: %s option not recognized\n",
ccname, argv[i]);
}
continue;
#endif mc68000
case 'B':
if (npassname)
error("-B overwrites earlier option", 0);
npassname = argv[i]+2;
if (npassname[0]==0)
npassname = "/usr/c/o";
continue;
case 'd':
dflag = argv[i];
continue;
case 'a':
if (strcmp(argv[i]+1,"align") == 0) {
if (i+1 >= argc || argv[i+1][0] == '-') {
fprintf(stderr,
"%s: missing argument to -align option\n", ccname);
continue;
}
llist[nl++] = "-align";
llist[nl++] = argv[++i];
continue;
}
aflag++;
continue;
case 'A':
/*
* There might be further chars after -A; we just
* pass them on to c2 as an extra argument -- later.
*/
continue;
case 'v':
vflag++;
continue;
}
t = argv[i];
cp = getsuf(t);
if (strequal(cp,"c") || strequal(cp,"s") || exflag) {
clist[nc++] = t;
t = setsuf(t, 'o');
} else if (strequal(cp, "il")) {
iflag++;
}
if (!strequal(cp, "il") && nodup(llist, t)) {
llist[nl++] = t;
if (strequal(getsuf(t),"o"))
nxo++;
}
}
if (outfile && cflag && nc == 1) {
asoutfile = outfile;
}
if (gflag || Gflag) {
if (oflag)
fprintf(stderr, "%s: warning: -g disables -O\n", ccname);
oflag = 0;
}
#ifdef mc68000
/*
* if no machine type specified, use the default
*/
if (machtype == NULL) {
machtype = default_machtype();
}
/*
* if no floating point machine type specified, use the default
*/
if (fptype == NULL) {
fptype = default_fptype(machtype);
} else if (unsupported(machtype, fptype)) {
t = fptype->optname;
fptype = default_fptype(machtype);
fprintf(stderr,
"%s: warning: %s option not supported with %s; %s used\n",
ccname, t, machtype->optname, fptype->optname);
}
machtype->found = 1;
fptype->found = 1;
#endif mc68000
if (npassname && chpass ==0)
chpass = "012pialc";
if (chpass && npassname==0)
npassname = "/usr/new/";
if (chpass)
for (t=chpass; *t; t++) {
switch (*t) {
case '0':
case '1':
ccom = strspl(npassname, "ccom");
continue;
case '2':
c2 = strspl(npassname, "c2");
continue;
case 'p':
cpp = strspl(npassname, "cpp");
continue;
case 'i':
inline = strspl(npassname, "inline");
continue;
case 'a':
as = strspl(npassname, "as");
continue;
case 'l':
ld = strspl(npassname, "ld");
continue;
case 'c':
libc = strspl(npassname, "libc.a");
chlibflag++;
continue;
}
}
if (nc==0)
goto nocom;
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, idexit);
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
signal(SIGTERM, idexit);
if (pflag==0)
sprintf(tmp0, "/tmp/ctm%05.5d", getpid());
/*
* rules of order:
* 1. The variables tmp[0-7] are set to the names of tmp files.
* 2. Do not set tmp[0-7] to names of other (non-temp) files
* 3. Unlink files when you're done with them.
* 4. Do not unlink anything except tmp[0-7] and the final
* .o in the case where a linked executable was produced
* and only one .[cs] file compiled.
*/
tmp1 = strspl(tmp0, "1"); /* default cpp output */
tmp2 = strspl(tmp0, "2"); /* default bb_count output */
tmp3 = strspl(tmp0, "3"); /* default inline input */
tmp4 = strspl(tmp0, "4"); /* default c2 input */
tmp5 = strspl(tmp0, "5"); /* default assembler input */
for (i=0; i<nc; i++) {
if (nc > 1) {
printf("%s:\n", clist[i]);
fflush(stdout);
}
if (strequal(getsuf(clist[i]), "s")) {
assource = clist[i];
goto assemble;
} else {
assource = tmp5;
}
if (pflag) {
cppout = setsuf(clist[i], 'i');
} else {
cppout = tmp1;
}
av[0] = "cpp"; av[1] = clist[i]; av[2] = exflag ? "-" : cppout;
na = 3;
for (j = 0; j < np; j++)
av[na++] = plist[j];
av[na++] = 0;
if (callsys(cpp, av)) {
exfail++;
eflag++;
}
if (pflag || exfail) {
cflag++;
continue;
}
/*
* Call the bb_count preprocessor
*/
if (aflag) {
av[0] = "bb_count";
av[1] = tmp1;
av[2] = clist[i];
av[3] = tmp2;
av[4] = 0;
if (callsys(count, av)) {
exfail++;
eflag++;
}
unlink(tmp1);
if (pflag || exfail) {
cflag++;
continue;
}
}
if (sflag)
assource = setsuf(clist[i], 's');
av[0] = "ccom";
av[1] = aflag? tmp2: tmp1;
av[2] = iflag? tmp3: oflag? tmp4: assource;
na = 3;
if (proflag)
av[na++] = "-XP";
if (Jflag)
av[na++] = "-XJ";
if (gflag) {
av[na++] = "-Xg";
} else if (Gflag) {
av[na++] = "-XG";
}
if (wflag)
av[na++] = "-w";
#ifdef mc68000
/* pass code gen options to ccom */
for (mp = machopts; mp->optname; mp++) {
if (mp->found) {
av[na++] = mp->optname;
}
}
for (mp = floatopts; mp->optname; mp++) {
if (mp->found) {
av[na++] = mp->optname;
}
}
#endif
av[na] = 0;
if (callsys(ccom, av)) {
cflag++;
eflag++;
continue;
}
unlink(tmp1);
unlink(tmp2);
if (iflag) {
/* run inline expansion */
av[0] = "inline";
av[1] = tmp3;
av[2] = "-o";
av[3] = oflag ? tmp4 : assource;
na = 4;
for (tmpi = 1; tmpi < argc; tmpi++) {
/* pass .i files to inline expander */
t = argv[tmpi];
if (strequal(getsuf(t), "il")) {
av[na++] = "-i";
av[na++] = t;
}
}
av[na] = 0;
if (callsys(inline, av)) {
cflag++;
eflag++;
continue;
}
unlink(tmp3);
}
if (oflag) {
av[0] = "c2";
av[1] = tmp4;
av[2] = assource;
na = 3;
av[na++] = (use68020 ? "-20" : "-10");
/* Pass -Oxxx arguments to optimizer */
for (tmpi = 1; tmpi < argc; tmpi++) {
if (argv[tmpi][0] == '-'
&& argv[tmpi][1] == 'O'
&& argv[tmpi][2] != '\0') {
av[na++] = argv[tmpi]+2;
}
}
av[na] = 0;
if (callsys(c2, av)) {
cflag++;
eflag++;
continue;
}
unlink(tmp4);
}
if (sflag)
continue;
assemble:
av[0] = "as";
av[1] = "-o";
if (asoutfile) {
av[2] = asoutfile;
} else {
av[2] = setsuf(clist[i], 'o');
}
na = 3;
av[na++] = (use68020 ? "-20" : "-10");
if (Rflag)
av[na++] = "-R";
if (dflag)
av[na++] = dflag;
/* Pass -Axxx arguments to assembler */
for (tmpi = 1; tmpi < argc; tmpi++) {
if (argv[tmpi][0] == '-'
&& argv[tmpi][1] == 'A'
&& argv[tmpi][2] != '\0') {
av[na++] = argv[tmpi]+2;
}
}
av[na++] = assource;
av[na] = 0;
if (callsys(as, av) > 1) {
cflag++;
eflag++;
continue;
}
}
nocom:
if (cflag==0 && nl!=0) {
i = 0;
na = 0;
av[na++] = "ld";
av[na++] = "-X";
av[na++] = strspl(chlibflag? npassname : "/lib/", crt0);
if (fptype->crt1 != NULL) {
av[na++] = strspl(chlibflag? npassname : "/lib/",
fptype->crt1);
}
if (outfile) {
av[na++] = "-o";
av[na++] = outfile;
}
while (i < nl)
av[na++] = llist[i++];
if (aflag)
av[na++] = "/usr/lib/bb_link.o";
if (gflag || Gflag)
av[na++] = "-lg";
if (proflag)
av[na++] = "-lc_p";
else
av[na++] = libc;
av[na++] = 0;
eflag |= callsys(ld, av);
if (nc==1 && nxo==1 && eflag==0)
unlink(setsuf(clist[0], 'o'));
}
dexit();
}
#ifdef mc68000
/*
* default target machine type is the same as host
*/
struct mach_info *
default_machtype()
{
return (is68020()? M_68020 : M_68010);
}
/*
* Floating point is such a zoo on this machine that
* nobody agrees what the default should be. So let
* the user decide, and to hell with it.
*/
struct mach_info *
default_fptype(mtp)
struct mach_info *mtp;
{
register char *env_string;
register struct mach_info *ftp;
env_string = getenv(FLOAT_OPTION);
if (env_string == NULL) {
return (F_soft);
}
for(ftp = floatopts; ftp->isatype; ftp++) {
if (!strcmp(ftp->optname+1, env_string)) {
if (unsupported(mtp, ftp)) {
ftp = F_soft;
fprintf(stderr,
"%s: warning: FLOAT_OPTION=%s not supported with %s; %s used\n",
ccname, env_string, mtp->optname+1, ftp->optname+1);
}
return(ftp);
}
}
ftp = F_soft;
fprintf(stderr,
"%s: warning: FLOAT_OPTION=%s not recognized; %s used\n",
ccname, env_string, ftp->optname+1);
return(ftp);
}
#endif mc68000
idexit()
{
eflag = 100;
dexit();
}
dexit()
{
if (!pflag) {
unlink(tmp1);
unlink(tmp2);
unlink(tmp3);
unlink(tmp4);
unlink(tmp5);
}
exit(eflag);
}
/*VARARGS1*/
error(s, x1, x2, x3, x4)
char *s;
{
FILE *diag = exflag ? stderr : stdout;
fprintf(diag, "%s: ", ccname);
fprintf(diag, s, x1, x2, x3, x4);
putc('\n', diag);
exfail++;
cflag++;
eflag++;
}
char *
getsuf(name)
char *name;
{
char *suff;
suff = rindex(name, '.');
if (suff == NULL)
return("");
return suff+1;
}
char *
setsuf(as, ch)
char *as;
{
register char *s, *s1;
s = s1 = savestr(as);
while (*s)
if (*s++ == '/')
s1 = s;
s[-1] = ch;
return (s1);
}
callsys(f, v)
char *f, **v;
{
int t, status;
#ifdef DEBUG
printf("fork %s:", f);
for (t = 0; v[t]; t++) printf(" %s", v[t][0]? v[t]: "(empty)");
printf("\n");
return 0;
#else DEBUG
if (vflag){
fprintf(stderr,"%s: ",f);
for (t = 0; v[t]; t++) fprintf(stderr, " %s", v[t][0]? v[t]: "(empty)");
fprintf(stderr, "\n");
}
fflush(stderr); /* purge any junk before the vfork */
t = vfork();
if (t == -1) {
fprintf( stderr, "%s: No more processes\n", ccname);
return (100);
}
if (t == 0) {
execv(f, v);
/*
* We are now in The Vfork Zone, and can't use "fprintf".
* We use "write" and "_perror" instead.
*/
write(2, ccname, strlen(ccname));
write(2, ": Can't execute ", 16);
_perror(f);
_exit(100);
}
while (t != wait(&status))
;
if ((t=(status&0377)) != 0 && t!=14) {
if (t!=2) {
fprintf( stderr, "%s: Fatal error in %s: %s%s\n", ccname, f, sys_siglist[t&0177], (t&0200)?" (core dumped)":"" );
eflag = 8;
}
dexit();
}
return ((status>>8) & 0377);
#endif DEBUG
}
nodup(l, os)
char **l, *os;
{
register char *t, *s;
register int c;
s = os;
if (!strequal(getsuf(s),"o"))
return (1);
while (t = *l++) {
while (c = *s++)
if (c != *t++)
break;
if (*t==0 && c==0)
return (0);
s = os;
}
return (1);
}
#define NSAVETAB 1024
char *savetab;
int saveleft;
char *
savestr(cp)
register char *cp;
{
register int len;
len = strlen(cp) + 1;
if (len > saveleft) {
saveleft = NSAVETAB;
if (len > saveleft)
saveleft = len;
savetab = malloc((unsigned)saveleft);
if (savetab == 0) {
fprintf(stderr, "%s: ran out of memory (savestr)\n", ccname);
exit(1);
}
}
strncpy(savetab, cp, len);
cp = savetab;
savetab += len;
saveleft -= len;
return (cp);
}
char *
strspl(left, right)
char *left, *right;
{
char buf[BUFSIZ];
strcpy(buf, left);
strcat(buf, right);
return (savestr(buf));
}

216
bin/chgrp.c Normal file
View File

@@ -0,0 +1,216 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char sccsid[] = "@(#)chgrp.c 1.1 92/07/30 SMI"; /* from UCB 5.7 6/4/86 */
#endif not lint
/*
* chgrp -fR gid file ...
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
#include <sys/dir.h>
#define MAXRET 254 /* ensure error status modulo 256 is non-zero */
struct group *gr, *getgrnam(), *getgrgid();
struct passwd *getpwuid(), *pwd;
struct stat stbuf;
int gid, uid;
int status;
int fflag, rflag;
/* VARARGS */
int fprintf();
main(argc, argv)
int argc;
char *argv[];
{
register c, i;
register char *cp;
argc--, argv++;
while (argc > 0 && argv[0][0] == '-') {
for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
case 'f':
fflag++;
break;
case 'r':
case 'R':
rflag++;
break;
default:
fatal(255, "unknown option: %c", *cp);
/*NOTREACHED*/
}
argv++, argc--;
}
if (argc < 2) {
fprintf(stderr, "usage: chgrp [-fR] gid file ...\n");
exit(255);
}
uid = geteuid();
if (isnumber(argv[0])) {
gid = atoi(argv[0]);
gr = getgrgid(gid);
if (uid && gr == NULL)
fatal(255, "%s: unknown group", argv[0]);
} else {
gr = getgrnam(argv[0]);
if (gr == NULL)
fatal(255, "%s: unknown group", argv[0]);
gid = gr->gr_gid;
}
pwd = getpwuid(uid);
if (pwd == NULL)
fatal(255, "Who are you?");
if (uid && pwd->pw_gid != gid) {
for (i=0; gr->gr_mem[i]; i++)
if (!(strcmp(pwd->pw_name, gr->gr_mem[i])))
goto ok;
if (fflag)
exit(0);
fatal(255, "You are not a member of the %s group", argv[0]);
}
ok:
for (c = 1; c < argc; c++) {
/* do stat for directory arguments */
if (lstat(argv[c], &stbuf)) {
status += Perror(argv[c]);
continue;
}
if (rflag && ((stbuf.st_mode & S_IFMT) == S_IFDIR)) {
status += chownr(argv[c], uid, gid);
continue;
}
if (uid && uid != stbuf.st_uid) {
status += error("You are not the owner of %s", argv[c]);
continue;
}
if (chown(argv[c], -1, gid)) {
status += Perror(argv[c]);
continue;
}
}
if (status > MAXRET)
status = MAXRET;
exit(status);
/* NOTREACHED */
}
isnumber(s)
char *s;
{
register int c;
while (c = *s++)
if (!isdigit(c))
return (0);
return (1);
}
chownr(dir, uid, gid)
char *dir;
{
register DIR *dirp;
register struct direct *dp;
register struct stat st;
char savedir[1024];
int ecode;
ecode = 0;
if (getwd(savedir) == 0)
fatal(255, "%s", savedir);
/*
* Change what we are given before doing its contents.
*/
if (lstat(dir, &st) < 0) {
Perror(dir);
return (1);
}
if (uid && uid != st.st_uid) {
ecode += error("You are not the owner of %s", dir);
} else if (chown(dir, -1, gid) < 0) {
ecode += Perror(dir);
}
if (chdir(dir) < 0) {
Perror(dir);
return (1);
}
if ((dirp = opendir(".")) == NULL) {
Perror(dir);
return (1);
}
dp = readdir(dirp);
dp = readdir(dirp); /* read "." and ".." */
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if (lstat(dp->d_name, &st) < 0) {
ecode += Perror(dp->d_name);
continue;
}
if ((st.st_mode & S_IFMT) == S_IFDIR) {
ecode += chownr(dp->d_name, uid, gid);
continue;
}
if (uid && uid != st.st_uid) {
ecode += error("You are not the owner of %s",
dp->d_name);
continue;
}
if (chown(dp->d_name, -1, gid) < 0) {
ecode += Perror(dp->d_name);
continue;
}
}
closedir(dirp);
if (chdir(savedir) < 0)
fatal(255, "can't change back to %s", savedir);
return (ecode);
}
error(fmt, a)
char *fmt, *a;
{
if (!fflag) {
fprintf(stderr, "chgrp: ");
fprintf(stderr, fmt, a);
putc('\n', stderr);
}
return (!fflag);
}
fatal(status, fmt, a)
int status;
char *fmt, *a;
{
fflag = 0;
(void) error(fmt, a);
exit(status);
}
Perror(s)
char *s;
{
if (!fflag) {
fprintf(stderr, "chgrp: ");
perror(s);
}
return (!fflag);
}

265
bin/cmp.c Normal file
View File

@@ -0,0 +1,265 @@
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1987 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* !lint */
#ifndef lint
static char sccsid[] = "@(#)cmp.c 1.1 92/07/30 SMI"; /* from UCB 4.5 11/18/87 */
#endif /* !lint */
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#define DIFF 1 /* found differences */
#define ERR 2 /* error during run */
#define NO 0 /* no/false */
#define OK 0 /* didn't find differences */
#define YES 1 /* yes/true */
static int fd1, /* descriptor, file 1 */
fd2, /* descriptor, file 2 */
silent = NO; /* if silent run */
static short all = NO; /* if report all differences */
static u_char buf1[MAXBSIZE], /* read buffers */
buf2[MAXBSIZE];
static char *file1, /* name, file 1 */
*file2; /* name, file 2 */
main(argc,argv)
int argc;
char **argv;
{
extern char *optarg; /* getopt externals */
extern int optind;
int ch; /* arguments */
u_long otoi();
while ((ch = getopt(argc,argv,"ls")) != EOF)
switch(ch) {
case 'l': /* print all differences */
all = YES;
break;
case 's': /* silent run */
silent = YES;
break;
case '?':
default:
usage();
}
argv += optind;
argc -= optind;
if (argc < 2 || argc > 4)
usage();
/* open up files; "-" is stdin */
file1 = argv[0];
if (strcmp(file1,"-") != 0 && (fd1 = open(file1,O_RDONLY)) < 0)
cantopen(file1);
file2 = argv[1];
if ((fd2 = open(file2,O_RDONLY)) < 0)
cantopen(file2);
/* handle skip arguments */
if (argc > 2) {
skip(otoi(argv[2]),fd1,file1);
if (argc == 4)
skip(otoi(argv[3]),fd2,file2);
}
cmp();
/*NOTREACHED*/
}
/*
* skip --
* skip first part of file
*/
static
skip(dist,fd,fname)
register u_long dist; /* length in bytes, to skip */
register int fd; /* file descriptor */
char *fname; /* file name for error */
{
register int rlen; /* read length */
register int nread;
for (;dist;dist -= rlen) {
rlen = MIN(dist,sizeof(buf1));
if ((nread = read(fd,buf1,rlen)) != rlen) {
if (nread < 0)
ioerror(fname);
else
endoffile(fname);
}
}
}
static
cmp()
{
register u_char *C1, /* traveling pointers */
*C2;
register int cnt, /* counter */
len1, /* read length 1 */
len2; /* read length 2 */
register long byte, /* byte count */
line; /* line count */
short dfound = NO; /* if difference found */
for (byte = 0,line = 1;;) {
switch(len1 = read(fd1,buf1,MAXBSIZE)) {
case -1:
ioerror(file1);
case 0:
/*
* read of file 1 just failed, find out
* if there's anything left in file 2
*/
switch(read(fd2,buf2,1)) {
case -1:
ioerror(file2);
case 0:
exit(dfound ? DIFF : OK);
default:
endoffile(file1);
}
}
/*
* file1 might be stdio, which means that a read of less than
* MAXBSIZE might not mean an EOF. So, read whatever we read
* from file1 from file2.
*/
if ((len2 = read(fd2,buf2,len1)) == -1)
ioerror(file2);
if (len2 == 0)
endoffile(file2);
if (bcmp(buf1,buf2,len2)) {
if (silent)
exit(DIFF);
if (all) {
dfound = YES;
for (C1 = buf1,C2 = buf2,cnt = len2;cnt--;++C1,++C2) {
++byte;
if (*C1 != *C2)
printf("%6ld %3o %3o\n",byte,*C1,*C2);
}
}
else for (C1 = buf1,C2 = buf2;;++C1,++C2) {
++byte;
if (*C1 != *C2) {
printf("%s %s differ: char %ld, line %ld\n",file1,file2,byte,line);
exit(DIFF);
}
if (*C1 == '\n')
++line;
}
}
else {
byte += len2;
/*
* here's the real performance problem, we've got to
* count the stupid lines, which means that -l is a
* *much* faster version, i.e., unless you really
* *want* to know the line number, run -s or -l.
*/
if (!silent && !all)
for (C1 = buf1,cnt = len2;cnt--;)
if (*C1++ == '\n')
++line;
}
/*
* couldn't read as much from file2 as from file1; checked
* here because there might be a difference before we got
* to this point, which would have precedence.
*/
if (len2 < len1)
endoffile(file2);
}
}
/*
* otoi --
* octal/decimal string to u_long
*/
static u_long
otoi(C)
register char *C; /* argument string */
{
register u_long val; /* return value */
register int base; /* number base */
base = (*C == '0') ? 8 : 10;
for (val = 0;isdigit(*C);++C)
val = val * base + *C - '0';
return(val);
}
/*
* usage --
* print usage and die
*/
static
usage()
{
fputs("usage: cmp [-ls] file1 file2 [skip1] [skip2]\n",stderr);
exit(ERR);
}
/*
* cantopen --
* print open error message and die
*/
cantopen(filename)
char *filename;
{
register int sverrno;
if (!silent) {
sverrno = errno;
(void) fprintf(stderr, "cmp: Can't open %s: ", filename);
errno = sverrno;
perror("");
}
exit(ERR);
}
/*
* ioerror --
* print I/O error message and die
*/
ioerror(filename)
char *filename;
{
register int sverrno;
if (!silent) {
sverrno = errno;
(void) fprintf(stderr, "cmp: I/O error on %s: ", filename);
errno = sverrno;
perror("");
}
exit(ERR);
}
/*
* endofffile --
* print end-of-file message and exit indicating the files were different
*/
endoffile(filename)
char *filename;
{
if (!silent)
(void) fprintf(stderr, "cmp: EOF on %s\n", filename);
exit(DIFF);
}

433
bin/cp.c Normal file
View File

@@ -0,0 +1,433 @@
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif not lint
#ifndef lint
static char sccsid[] = "@(#)cp.c 1.1 92/07/30 SMI"; /* from UCB 4.13 10/11/85 */
#endif not lint
/*
* cp
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <sys/time.h>
#include <sys/mman.h>
#ifndef MAXMAPSIZE
#define MAXMAPSIZE (256*1024)
#endif
int iflag;
int rflag;
int pflag;
int zflag;
char *rindex();
caddr_t mmap();
main(argc, argv)
int argc;
char **argv;
{
struct stat stb;
int rc, i;
argc--, argv++;
while (argc > 0 && **argv == '-') {
(*argv)++;
while (**argv) switch (*(*argv)++) {
case 'i':
iflag++; break;
case 'R':
case 'r':
rflag++; break;
case 'p': /* preserve mtimes, atimes, and modes */
pflag++;
(void) umask(0);
break;
default:
goto usage;
}
argc--; argv++;
}
if (argc < 2)
goto usage;
if (argc > 2) {
if (stat(argv[argc-1], &stb) < 0)
goto usage;
if ((stb.st_mode&S_IFMT) != S_IFDIR)
goto usage;
}
rc = 0;
for (i = 0; i < argc-1; i++)
rc |= copy(argv[i], argv[argc-1]);
exit(rc);
usage:
(void) fprintf(stderr,
"Usage: cp [-ip] f1 f2; or: cp [-ipr] f1 ... fn d2\n");
exit(1);
/* NOTREACHED */
}
copy(from, to)
char *from, *to;
{
int fold, fnew, n, exists;
char *last, destname[MAXPATHLEN + 1], buf[MAXBSIZE];
struct stat stfrom, stto;
register caddr_t cp;
int mapsize, munmapsize;
register off_t filesize;
register off_t offset;
fold = open(from, 0);
if (fold < 0) {
Perror(from);
return (1);
}
if (fstat(fold, &stfrom) < 0) {
Perror(from);
(void) close(fold);
return (1);
}
if (stat(to, &stto) >= 0 &&
(stto.st_mode&S_IFMT) == S_IFDIR) {
last = rindex(from, '/');
if (last) last++; else last = from;
if (strlen(to) + strlen(last) >= sizeof destname - 1) {
(void) fprintf(stderr, "cp: %s/%s: Name too long\n",
to, last);
(void) close(fold);
return(1);
}
(void) sprintf(destname, "%s/%s", to, last);
to = destname;
}
if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR) {
int fixmode = 0; /* cleanup mode after rcopy */
(void) close(fold);
if (stat(to, &stto) < 0) {
if (mkdir(to,
((int)stfrom.st_mode & 07777) | 0700) < 0) {
Perror(to);
return (1);
}
fixmode = 1;
} else if ((stto.st_mode&S_IFMT) != S_IFDIR) {
(void) fprintf(stderr, "cp: %s: Not a directory.\n",
to);
return (1);
} else if (pflag)
fixmode = 1;
n = rcopy(from, to);
if (fixmode)
(void) chmod(to, (int)stfrom.st_mode & 07777);
return (n);
}
if ((stfrom.st_mode&S_IFMT) == S_IFDIR) {
(void) close(fold);
(void) fprintf(stderr, "cp: %s: Is a directory (not copied).\n",
from);
return (1);
}
exists = stat(to, &stto) == 0;
if (exists) {
if (stfrom.st_dev == stto.st_dev &&
stfrom.st_ino == stto.st_ino) {
(void) fprintf(stderr,
"cp: %s and %s are identical (not copied).\n",
from, to);
(void) close(fold);
return (1);
}
if (iflag && isatty(fileno(stdin))) {
int i, c;
(void) fprintf (stderr, "overwrite %s? ", to);
i = c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
if (i != 'y') {
(void) close(fold);
return(1);
}
}
}
fnew = creat(to, (int)stfrom.st_mode & 07777);
if (fnew < 0) {
Perror(to);
(void) close(fold); return(1);
}
if (exists && pflag)
(void) fchmod(fnew, (int)stfrom.st_mode & 07777);
zopen(fnew, zflag);
if ((stfrom.st_mode & S_IFMT) == S_IFREG) {
/*
* Determine size of initial mapping. This will determine
* the size of the address space chunk we work with. This
* initial mapping size will be used to perform munmap() in
* the future.
*/
mapsize = MAXMAPSIZE;
if (stfrom.st_size < mapsize)
mapsize = stfrom.st_size;
munmapsize = mapsize;
/*
* Mmap time!
*/
cp = mmap((caddr_t)NULL, mapsize, PROT_READ, MAP_SHARED, fold,
(off_t)0);
if (cp == (caddr_t)-1)
mapsize = 0; /* I guess we can't mmap today */
} else
mapsize = 0; /* can't mmap non-regular files */
if (mapsize != 0) {
offset = 0;
filesize = stfrom.st_size;
#ifdef MC_ADVISE
(void) madvise(cp, mapsize, MADV_SEQUENTIAL);
#endif
for (;;) {
if (zwrite(fnew, cp, mapsize) < 0) {
Perror(to);
(void) close(fold);
(void) close(fnew);
(void) munmap(cp, munmapsize);
return (1);
}
filesize -= mapsize;
if (filesize == 0)
break;
offset += mapsize;
if (filesize < mapsize)
mapsize = filesize;
if (mmap(cp, mapsize, PROT_READ, MAP_SHARED | MAP_FIXED,
fold, offset) == (caddr_t)-1) {
Perror(from);
(void) close(fold);
(void) close(fnew);
(void) munmap(cp, munmapsize);
return (1);
}
#ifdef MC_ADVISE
(void) madvise(cp, mapsize, MADV_SEQUENTIAL);
#endif
}
(void) munmap(cp, munmapsize);
} else {
for (;;) {
n = read(fold, buf, sizeof buf);
if (n == 0)
break;
if (n < 0) {
Perror(from);
(void) close(fold);
(void) close(fnew);
return (1);
}
if (zwrite(fnew, buf, n) < 0) {
Perror(to);
(void) close(fold);
(void) close(fnew);
return (1);
}
}
}
(void) close(fold);
if (zclose(fnew) < 0) {
Perror(to);
(void) close(fnew);
return (1);
}
if (close(fnew) < 0) {
Perror(to);
return (1);
}
if (pflag)
return (setimes(to, &stfrom));
return (0);
}
rcopy(from, to)
char *from, *to;
{
DIR *fold = opendir(from);
struct direct *dp;
struct stat statb;
int errs = 0;
char fromname[MAXPATHLEN + 1];
if (fold == 0 || (pflag && fstat(fold->dd_fd, &statb) < 0)) {
Perror(from);
return (1);
}
for (;;) {
dp = readdir(fold);
if (dp == 0) {
(void) closedir(fold);
if (pflag)
return (setimes(to, &statb) + errs);
return (errs);
}
if (dp->d_ino == 0)
continue;
if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
continue;
if (strlen(from)+1+strlen(dp->d_name) >= sizeof fromname - 1) {
(void) fprintf(stderr, "cp: %s/%s: Name too long\n",
from, dp->d_name);
errs++;
continue;
}
(void) sprintf(fromname, "%s/%s", from, dp->d_name);
errs += copy(fromname, to);
}
}
int
setimes(path, statp)
char *path;
struct stat *statp;
{
struct timeval tv[2];
tv[0].tv_sec = statp->st_atime;
tv[1].tv_sec = statp->st_mtime;
tv[0].tv_usec = tv[1].tv_usec = 0;
if (utimes(path, tv) < 0) {
Perror(path);
return (1);
}
return (0);
}
Perror(s)
char *s;
{
(void) fprintf(stderr, "cp: ");
perror(s);
}
/*
* sparse file support
*/
#include <errno.h>
#include <sys/file.h>
static int zbsize;
static int zlastseek;
off_t lseek();
/* is it ok to try to create holes? */
zopen(fd, flag)
int fd;
{
struct stat st;
zbsize = 0;
zlastseek = 0;
if (flag &&
fstat(fd, &st) == 0 &&
(st.st_mode & S_IFMT) == S_IFREG)
zbsize = st.st_blksize;
}
/* write and/or seek */
zwrite(fd, buf, nbytes)
int fd;
register char *buf;
register int nbytes;
{
register int block = zbsize ? zbsize : nbytes;
do {
if (block > nbytes)
block = nbytes;
nbytes -= block;
if (!zbsize || notzero(buf, block)) {
register int n, count = block;
do {
if ((n = write(fd, buf, count)) < 0)
return -1;
buf += n;
} while ((count -= n) > 0);
zlastseek = 0;
}
else {
if (lseek(fd, (off_t) block, L_INCR) < 0)
return -1;
buf += block;
zlastseek = 1;
}
} while (nbytes > 0);
return 0;
}
/* write last byte of file if necessary */
zclose(fd)
int fd;
{
zbsize = 0;
if (zlastseek &&
(lseek(fd, (off_t) -1, L_INCR) < 0 ||
zwrite("", 1) < 0))
return -1;
else
return 0;
}
/* return true if buffer is not all zeros */
notzero(p, n)
register char *p;
register int n;
{
register int result = 0;
while ((int) p & 3 && --n >= 0)
result |= *p++;
while ((n -= 4 * sizeof (int)) >= 0) {
result |= ((int *) p)[0];
result |= ((int *) p)[1];
result |= ((int *) p)[2];
result |= ((int *) p)[3];
if (result)
return result;
p += 4 * sizeof (int);
}
n += 4 * sizeof (int);
while (--n >= 0)
result |= *p++;
return result;
}

83
bin/csh/Makefile Normal file
View File

@@ -0,0 +1,83 @@
#
# Copyright (c) 1980 Regents of the University of California.
# All rights reserved. The Berkeley Software License Agreement
# specifies the terms and conditions for redistribution.
#
# @(#) Makefile 1.1 92/07/30 SMI; from UCB 5.3 3/29/86
#
# C Shell with process control; VM/UNIX VAX Makefile
# Bill Joy UC Berkeley; Jim Kulp IIASA, Austria
#
# To profile, put -DPROF in DEFS and -pg in CFLAGS, and recompile.
.KEEP_STATE:
.FRC:
BINS = csh
BINDIR = $(DESTDIR)/usr/bin
LOCAL_HDRS = sh.h sh.local.h sh.dir.h param.h sh.char.h sh.proc.h sh.tconst.h
#DEFS= -DTELL -DVFORK -DFILEC -DDBG -DTRACE
DEFS= -DTELL -DVFORK -DFILEC
#MBCHAR= -DMBCHAR # Define this to make multibyte char version.
#CFLAGS= $(DEFS) $(MBCHAR) -O
CFLAGS= $(DEFS) $(MBCHAR) -I/usr/src/include -O
LINK_LIBS= -ltermlib
# doprnt.* removed from OBJS for Sun.
SRCS= printf.c sh.c sh.char.c sh.dir.c sh.dol.c sh.err.c \
sh.exec.c sh.exp.c sh.file.c sh.func.c sh.glob.c sh.hist.c sh.init.c \
sh.lex.c sh.misc.c sh.parse.c sh.print.c sh.proc.c sh.sem.c sh.set.c \
sh.time.c sh.tchar.c sh.tconst.c sh.debug.c
OBJS= printf.o sh.o sh.char.o sh.dir.o sh.dol.o sh.err.o \
sh.exec.o sh.exp.o sh.file.o sh.func.o sh.glob.o sh.hist.o sh.init.o \
sh.lex.o sh.misc.o sh.parse.o sh.print.o sh.proc.o sh.sem.o sh.set.o \
sh.time.o sh.tchar.o sh.tconst.o sh.debug.o
.INIT: $(HDRS) $(LOCAL_HDRS)
bins: $(BINS)
# Special massaging of C files for sharing of strings
.c.o:
$(CC) -E $(CFLAGS) $*.c | xstr -c -
$(CC) -c $(CFLAGS) x.c
mv -f x.o $*.o
rm -f x.c
# strings.o must be last since it can change when previous files compile
csh: $(OBJS) strings.o
rm -f csh
$(CC) $(OBJS) strings.o -o csh $(LINK_LIBS)
# strings.o, sh.init.o, and sh.char.o are specially processed to be shared
strings.o: strings
xstr
$(CC) -c -R xs.c
mv -f xs.o strings.o
rm -f xs.c
strings: $(OBJS)
sh.char.o sh.init.o sh.tconst.o:
$(CC) -E $(CFLAGS) $*.c | xstr -c -
$(CC) $(CFLAGS) -c -R x.c
mv -f x.o $*.o
rm -f x.c
sh.tconst.h: sh.tconst.c make.sh.tconst.h.ed #sh.tconst.h is made
rm -f sh.tconst.h
ed sh.tconst.c < make.sh.tconst.h.ed #from sh.tconst.c
chmod 777 sh.tconst.h
install: $(BINS)
install -m 775 -d $(BINDIR)
install -s $(BINS) $(BINDIR)
install_h:
clean:
-rm -rf $(LOCAL_BINS) $(BINS) $(LOCAL_LIBS) $(LIBS) $(OBJS) \
core a.out install_bins sh.tconst.h strings x.c xs.c strings.o

27
bin/csh/README Normal file
View File

@@ -0,0 +1,27 @@
Wed Mar 5 13:54:45 PST 1986
The C shell now incorporates filename expansion directly, controlled
by whether or not the shell variable "filec" is set. Thus, there's
no longer any reason to build csh and tcsh separately.
This change and others pertaining to the 4.3 merge have induced some
changes in the source file structure.
Renamed:
tenex.c --> sh.file.c
Obsolete:
malloc.c
sh.sig.c
tgt.mk
To recreate an early verson of the shell, the renaming will have to be
undone.
***********************************************************************
Fri May 6 22:20:14 PDT 1988
The C shell now incorporate 8bit characters.
If INTER is defined, csh will be 8bit clean version.
The debug routines are gathered in sh.debug.c.
A new file sh.8bit.c is created.

396
bin/csh/alloc.c Normal file
View File

@@ -0,0 +1,396 @@
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)alloc.c 1.1 92/07/30 SMI; from UCB 5.3 3/29/86";
#endif
/*
* UCB's version 5.3 in turn derived from their
* malloc.c version 5.5 2/25/86.
*/
/*
* malloc.c (Caltech) 2/21/82
* Chris Kingsley, kingsley@cit-20.
*
* This is a very fast storage allocator. It allocates blocks of a small
* number of different sizes, and keeps free lists of each size. Blocks that
* don't exactly fit are passed up to the next larger size. In this
* implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
* This is designed for use in a virtual memory environment.
*/
/*
* Use "#define OLDMALLOC" to include this code. Otherwise, the system's
* malloc/free routines will be linked in.
*/
#ifdef OLDMALLOC
#include <sys/types.h>
#define NULL 0
/*
* The overhead on a block is at least 4 bytes. When free, this space
* contains a pointer to the next free block, and the bottom two bits must
* be zero. When in use, the first byte is set to MAGIC, and the second
* byte is the size index. The remaining bytes are for alignment.
* If range checking is enabled then a second word holds the size of the
* requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
* The order of elements is critical: ov_magic must overlay the low order
* bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
*/
union overhead {
union overhead *ov_next; /* when free */
struct {
u_char ovu_magic; /* magic number */
u_char ovu_index; /* bucket # */
#ifdef RCHECK
u_short ovu_rmagic; /* range magic number */
u_int ovu_size; /* actual block size */
#endif
} ovu;
#define ov_magic ovu.ovu_magic
#define ov_index ovu.ovu_index
#define ov_rmagic ovu.ovu_rmagic
#define ov_size ovu.ovu_size
};
#define MAGIC 0xef /* magic # on accounting info */
#define RMAGIC 0x5555 /* magic # on range info */
#ifdef RCHECK
#define RSLOP sizeof (u_short)
#else
#define RSLOP 0
#endif
/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information
* precedes the data area returned to the user.
*/
#define NBUCKETS 30
static union overhead *nextf[NBUCKETS];
extern char *sbrk();
static int pagesz; /* page size */
static int pagebucket; /* page size bucket */
/*
* nmalloc[i] is the difference between the number of mallocs and frees
* for a given block size.
*/
static u_int nmalloc[NBUCKETS];
#if defined(DEBUG) || defined(RCHECK)
#define ASSERT(p) if (!(p)) botch("p")
static
botch(s)
char *s;
{
printf("\r\nassertion botched: %s\r\n", s);
abort();
}
#else
#define ASSERT(p)
#endif
char *
malloc(nbytes)
unsigned nbytes;
{
register union overhead *op;
register int bucket;
register unsigned amt, n;
/*
* First time malloc is called, setup page size and
* align break pointer so all data will be page aligned.
*/
if (pagesz == 0) {
pagesz = n = getpagesize();
op = (union overhead *)sbrk(0);
n = n - sizeof (*op) - ((int)op & (n - 1));
if (n < 0)
n += pagesz;
if (n) {
if (sbrk(n) == (char *)-1)
return (NULL);
}
bucket = 0;
amt = 8;
while (pagesz > amt) {
amt <<= 1;
bucket++;
}
pagebucket = bucket;
}
/*
* Convert amount of memory requested into closest block size
* stored in hash buckets which satisfies request.
* Account for space used per block for accounting.
*/
if (nbytes <= (n = pagesz - sizeof (*op) - RSLOP)) {
#ifndef RCHECK
amt = 8; /* size of first bucket */
bucket = 0;
#else
amt = 16; /* size of first bucket */
bucket = 1;
#endif
n = -(sizeof (*op) + RSLOP);
} else {
amt = pagesz;
bucket = pagebucket;
}
while (nbytes > amt + n) {
amt <<= 1;
if (amt == 0)
return (NULL);
bucket++;
}
/*
* If nothing in hash bucket right now,
* request more memory from the system.
*/
if ((op = nextf[bucket]) == NULL) {
morecore(bucket);
if ((op = nextf[bucket]) == NULL)
return (NULL);
}
/* remove from linked list */
nextf[bucket] = op->ov_next;
op->ov_magic = MAGIC;
op->ov_index = bucket;
nmalloc[bucket]++;
#ifdef RCHECK
/*
* Record allocated size of block and
* bound space with magic numbers.
*/
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
op->ov_rmagic = RMAGIC;
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
return ((char *)(op + 1));
}
/*
* Allocate more memory to the indicated bucket.
*/
morecore(bucket)
int bucket;
{
register union overhead *op;
register int sz; /* size of desired block */
int amt; /* amount to allocate */
int nblks; /* how many blocks we get */
/*
* sbrk_size <= 0 only for big, FLUFFY, requests (about
* 2^30 bytes on a VAX, I think) or for a negative arg.
*/
sz = 1 << (bucket + 3);
#ifdef DEBUG
ASSERT(sz > 0);
#else
if (sz <= 0)
return;
#endif
if (sz < pagesz) {
amt = pagesz;
nblks = amt / sz;
} else {
amt = sz + pagesz;
nblks = 1;
}
op = (union overhead *)sbrk(amt);
/* no more room! */
if ((int)op == -1)
return;
/*
* Add new memory allocated to that on
* free list for this hash bucket.
*/
nextf[bucket] = op;
while (--nblks > 0) {
op->ov_next = (union overhead *)((caddr_t)op + sz);
op = (union overhead *)((caddr_t)op + sz);
}
}
free(cp)
char *cp;
{
register int size;
register union overhead *op;
if (cp == NULL)
return;
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
/*
* The following botch is because csh tries to free a free block
* when processing the =~ or !~ operators. -- layer@ucbmonet
*/
#ifdef CSHbotch /* was DEBUG */
ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
#else
if (op->ov_magic != MAGIC)
return; /* sanity */
#endif
#ifdef RCHECK
ASSERT(op->ov_rmagic == RMAGIC);
ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
#endif
size = op->ov_index;
ASSERT(size < NBUCKETS);
op->ov_next = nextf[size]; /* also clobbers ov_magic */
nextf[size] = op;
nmalloc[size]--;
}
/*
* When a program attempts "storage compaction" as mentioned in the
* old malloc man page, it realloc's an already freed block. Usually
* this is the last block it freed; occasionally it might be farther
* back. We have to search all the free lists for the block in order
* to determine its bucket: 1st we make one pass thru the lists
* checking only the first block in each; if that fails we search
* ``realloc_srchlen'' blocks in each list for a match (the variable
* is extern so the caller can modify it). If that fails we just copy
* however many bytes was given to realloc() and hope it's not huge.
*/
int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
char *
realloc(cp, nbytes)
char *cp;
unsigned nbytes;
{
register u_int onb, i;
union overhead *op;
char *res;
int was_alloced = 0;
if (cp == NULL)
return (malloc(nbytes));
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
if (op->ov_magic == MAGIC) {
was_alloced++;
i = op->ov_index;
} else {
/*
* Already free, doing "compaction".
*
* Search for the old block of memory on the
* free list. First, check the most common
* case (last element free'd), then (this failing)
* the last ``realloc_srchlen'' items free'd.
* If all lookups fail, then assume the size of
* the memory block being realloc'd is the
* largest possible (so that all "nbytes" of new
* memory are copied into). Note that this could cause
* a memory fault if the old area was tiny, and the moon
* is gibbous. However, that is very unlikely.
*/
if ((i = findbucket(op, 1)) < 0 &&
(i = findbucket(op, realloc_srchlen)) < 0)
i = NBUCKETS;
}
onb = 1 << (i + 3);
if (onb < pagesz)
onb -= sizeof (*op) + RSLOP;
else
onb += pagesz - sizeof (*op) - RSLOP;
/* avoid the copy if same size block */
if (was_alloced) {
if (i) {
i = 1 << (i + 2);
if (i < pagesz)
i -= sizeof (*op) + RSLOP;
else
i += pagesz - sizeof (*op) - RSLOP;
}
if (nbytes <= onb && nbytes > i) {
#ifdef RCHECK
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
return(cp);
} else
free(cp);
}
if ((res = malloc(nbytes)) == NULL)
return (NULL);
if (cp != res) /* common optimization if "compacting" */
bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
return (res);
}
/*
* Search ``srchlen'' elements of each free list for a block whose
* header starts at ``freep''. If srchlen is -1 search the whole list.
* Return bucket number, or -1 if not found.
*/
static
findbucket(freep, srchlen)
union overhead *freep;
int srchlen;
{
register union overhead *p;
register int i, j;
for (i = 0; i < NBUCKETS; i++) {
j = 0;
for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
if (p == freep)
return (i);
j++;
}
}
return (-1);
}
#endif OLDMALLOC
/*
* mstats - print out statistics about malloc
*
* Prints two lines of numbers, one showing the length of the free list
* for each size category, the second showing the number of mallocs -
* frees for each size category.
*/
showall(s)
char **s;
{
#ifdef OLDMALLOC
register int i, j;
register union overhead *p;
int totfree = 0,
totused = 0;
if (s[1])
printf("Memory allocation statistics %s\nfree:", s[1]);
for (i = 0; i < NBUCKETS; i++) {
for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
;
if (s[1])
printf(" %d", j);
totfree += j * (1 << (i + 3));
}
if (s[1])
printf("\nused:");
for (i = 0; i < NBUCKETS; i++) {
if (s[1])
printf(" %d", nmalloc[i]);
totused += nmalloc[i] * (1 << (i + 3));
}
if (s[1])
printf("\n");
printf("Total in use: %d, total free: %d\n", totused, totfree);
#endif OLDMALLOC
}

475
bin/csh/doprnt.c Normal file
View File

@@ -0,0 +1,475 @@
.data
.asciz "@(#)doprnt.c 1.1 92/07/30 SMI; from UCB 4.1 80/10/09";
.text
# C library -- conversions
.globl __doprnt
.globl __strout
#define flags r10
#define literb 0
#define liter 1
#define ndfndb 0
#define ndfnd 1
#define ljustb 1
#define ljust 2
#define zfillb 2
#define zfill 4
#define precb 3
#define prec 8
#define psignb 4
#define psign 16
#define gflagb 5
#define gflag 32
#define width r9
#define ndigit r8
#define fdesc -4(fp)
#define exp -8(fp)
#define sign -9(fp)
.set one,010 # 1.0 in floating immediate
.set ch.zer,'0 # cpp doesn't like single appostrophes
.align 1
__doprnt:
.word 0xfc0 # uses r11-r6
subl2 $128,sp
movl 4(ap),r11 # addr of format string
movl 12(ap),fdesc # output FILE ptr
movl 8(ap),ap # addr of first arg
loop:
movl r11,r0 # current point in format
bicl2 $liter,flags # no literal characters yet
L1: movb (r11)+,width # next character of format
beql L2 # end of format string
cmpb width,$'%
beql L2 # warning character
bisl2 $liter,flags # literal character
jbr L1
L2: blbc flags,L3 # bbc $literb,flags,L3 # no literals in format
pushl fdesc # file pointer
pushl $0 # no left/right adjust
pushl r0 # addr
subl3 r0,r11,r1 # length
subl3 $1,r1,-(sp) # % or null not part of literal
calls $4,__strout # dump the literal
L3:
blbs width,L4 # % is odd; end of format?
ret # yes
# htab overlaps last 16 characters of ftab
ftab: .byte 0, 0, 0,'c,'d,'e,'f,'g, 0, 0, 0,'+,'l,'-,'.,'o
htab: .byte '0,'1,'2,'3,'4,'5,'6,'7,'8,'9,'a,'b,'c,'d,'e,'f
L4: movl sp,r5 # reset output buffer pointer
clrq r9 # width; flags ljustb,ndfndb,zfillb
L4a: movzbl (r11)+,r0 # supposed format
extzv $0,$5,r0,r1 # bottom 5 bits
L4b: cmpb r0,ftab[r1] # good enough?
jneq L6 # no
L4c: casel r1,$3,$22 # yes
L5: .word charac-L5 # c
.word decimal-L5 # d
.word scien-L5 # e
.word float-L5 # f
.word general-L5 # g
.word L6-L5 # h
.word L6-L5 # i
.word L6-L5 # j
.word plus-L5 # +
.word longorunsg-L5 # l
.word minus-L5 # -
.word dot-L5 # .
.word octal-L5 # o
.word gnum0-L5 # 0
.word gnum-L5 # 1
.word gnum-L5 # 2
.word gnum-L5 # 3
.word gnum-L5 # 4
.word gnum-L5 # 5
.word gnum-L5 # 6
.word gnum-L5 # 7
.word gnum-L5 # 8
.word gnum-L5 # 9
L6: jbcs $5,r0,L4b # capitals same as small
cmpb r0,$'s
jeql string
cmpb r0,$'x
jeql hex
cmpb r0,$'u
jeql unsigned
cmpb r0,$'r
jeql remote
movzbl -1(r11),r0 # orginal "format" character
cmpb r0,$'*
jeql indir
L9: movb r0,(r5)+ # print the unfound character
jbr prbuf
nulstr:
.byte '(,'n,'u,'l,'l,'),0
string:
movl ndigit,r0
jbs $precb,flags,L20 # max length was specified
mnegl $1,r0 # default max length
L20: movl (ap)+,r2 # addr first byte
bneq L21
movab nulstr,r2
L21: locc $0,r0,(r2) # find the zero at the end
movl r1,r5 # addr last byte +1
movl r2,r1 # addr first byte
jbr prstr
longorunsg:
movb (r11)+,r0
cmpb r0,$'o
jeql loct
cmpb r0,$'x
jeql lhex
cmpb r0,$'d
jeql long
cmpb r0,$'u
jeql lunsigned
decl r11
jbr unsigned
loct:
octal:
movl $30,r2 # init position
movl $3,r3 # field width
movl $10,r4 # result length -1
jbr L10
lhex:
hex:
movl $28,r2 # init position
movl $4,r3 # field width
movl $7,r4 # result length -1
L10: mnegl r3,r6 # increment
clrl r1
movl (ap)+,r0 # fetch arg
L11: extzv r2,r3,r0,r1 # pull out a digit
movb htab[r1],(r5)+ # convert to character
L12: acbl $0,r6,r2,L11 # continue until done
clrb (r5) # flag end
skpc $'0,r4,(sp) # skip over leading zeroes
jbr prstr
patdec: # editpc pattern for decimal printing
.byte 0xA9 # eo$float 9
.byte 0x01 # eo$end_float
.byte 0x91 # eo$move 1
.byte 0 # eo$end
long:
decimal:
cvtlp (ap)+,$10,(sp) # 10 digits max
L14: editpc $10,(sp),patdec,8(sp) # ascii at 8(sp); r5=end+1
skpc $' ,$10,8(sp) # skip leading blanks; r1=first
prstr: # r1=addr first byte; r5=addr last byte +1
cvtbl $' ,-(sp) # blank fill
jbc $zfillb,flags,L15
cvtbl $'0,(sp) # zero fill
L15: pushl fdesc # FILE
subl2 r1,r5 # r5=actual length=end+1-first
subl3 r5,width,r0 # if >0, how much to fill
bgeq L24
clrl r0 # no fill
L24: jbs $ljustb,flags,L25
mnegl r0,r0
L25: pushl r0 # fill count
pushl r1 # addr first byte
pushl r5 # length
calls $5,__strout
jbr loop
pone: .byte 0x1C # packed 1
unsigned:
lunsigned:
extzv $1,$31,(ap),r0 # right shift logical 1 bit
cvtlp r0,$10,(sp) # convert [n/2] to packed
movp $10,(sp),8(sp) # copy packed
addp4 $10,8(sp),$10,(sp) # 2*[n/2] in packed, at (sp)
blbc (ap)+,L14 # n was even
addp4 $1,pone,$10,(sp) # n was odd
jbr L14
charac:
movl $4,r0 # chars per word
L18: movb (ap)+,(r5)+ # transfer char
bneq L19
decl r5 # omit null characters
L19: sobgtr r0,L18
prbuf:
movl sp,r1 # addr first byte
jbr prstr
plus: bisl2 $psign,flags # always print sign for floats
jbr L4a
minus: bisl2 $ljust,flags # left justification, please
jbr L4a
gnum0: jbs $ndfndb,flags,gnum
jbs $precb,flags,gnump # ignore when reading precision
bisl2 $zfill,flags # leading zero fill, please
gnum: jbs $precb,flags,gnump
moval (width)[width],width # width *= 5;
movaw -ch.zer(r0)[width],width # width = 2*witdh + r0 - '0';
jbr gnumd
gnump: moval (ndigit)[ndigit],ndigit # ndigit *= 5;
movaw -ch.zer(r0)[ndigit],ndigit # ndigit = 2*ndigit + r0 - '0';
gnumd: bisl2 $ndfnd,flags # digit seen
jbr L4a
dot: clrl ndigit # start on the precision
bisl2 $prec,flags
bicl2 $ndfnd,flags
jbr L4a
indir: movl (ap)+,ndigit # width specified by parameter
jbr gnumd
remote: movl (ap)+,ap
movl (ap)+,r11
jbr loop
float:
bsbw fltcvt
fltg: jbs $ndfndb,flags,float1
movl $6,ndigit # default # digits to right of decpt.
float1: addl3 exp,ndigit,r7
movl r7,r6 # for later "underflow" checking
bgeq fxplrd
clrl r7 # poor programmer planning
fxplrd: cmpl r7,$31 # expressible in packed decimal?
bleq fnarro # yes
movl $31,r7
fnarro: subl3 $17,r7,r0 # where to round
ashp r0,$17,(sp),$5,r7,16(sp) # do it
bvc fnovfl
# band-aid for microcode error (spurious overflow)
clrl r0 # assume even length result
jlbc r7,fleven # right
movl $4,r0 # odd length result
fleven: cmpv r0,$4,16(sp),$0 # top digit zero iff true overflow
bneq fnovfl
# end band-aid
aobleq $0,r6,fnovfl # if "underflow" then jump
movl r7,r0
incl exp
incl r7
ashp r0,$1,pone,$0,r7,16(sp)
ashl $-1,r7,r0 # displ to last byte
bisb2 sign,16(sp)[r0] # insert sign
fnovfl:
movc3 $4,patsci,(sp)
clrl r6 # # digits moved so far
movl exp,r0
bleq fexpng
bsbb patmov # digits to left of decpt.
fexpng: tstl ndigit
jeql fnodp
movc3 $2,fpatdp,(r3)
tstl exp
bgeq fxppos
addl3 exp,ndigit,r6
bgeq flfakl
clrl r6 # it's all fill
flfakl: subl3 r6,$31,r6 # fake length for patmov
flfill: movc3 $2,fpatzf,(r3) # zero fill to right of dec.pt
fxppos: movl ndigit,r0
bsbb patmov
fnodp: sobgeq r6,fledit # must move at least 1 digit
movl $31,r6 # none moved; fake it
aobleq $1,ndigit,flfill # with a one-character zero fill
fledit: editpc r7,16(sp),(sp),32(sp)
jbr prflt
patexp: .byte 0x03 # eo$set_signif
.byte 0x44,'e # eo$insert 'e
.byte 0x42,'+ # eo$load_plus '+
.byte 0x04 # eo$store_sign
.byte 0x92 # eo$move 2
.byte 0 # eo$end
patsci: .byte 0x42,'+ # eo$load_plus '+
.byte 0x03 # eo$set_signif
.byte 0x04 # eo$store_sign
.byte 0x91 # eo$move 1
fpatdp: .byte 0x44,'. # eo$insert '.
fpatzf: .byte 0x40,'0 # eo$load_fill '0
# construct pattern at (r3) to move r0 digits in editpc;
# r6 digits already moved for this number
patmov:
movb $0x90,r2 # eo$move
subl3 r6,$31,r1 # # digits remaining in packed
addl2 r0,r6
cmpl r0,r1 # enough digits remaining?
bleq patsml # yes
tstl exp # zero 'fill'; before or after rest?
bgeq pataft # after
pushl r1 # # digits remaining
movb $0x80,r2 # eo$fill
subl3 $31,r6,r0 # number of fill bytes
bsbb patsml # recursion!
movl (sp)+,r0
movb $0x90,r2 # eo$move
jbr patsml
pataft: movl r1,r0 # last of the 31
bsbb patsml # recursion!
subl3 $31,r6,r0 # number of fill bytes
movb $0x80,r2 # eo$fill
patsml: tstl r0
bleq patzer # DEC doesn't like repetition counts of 0
mnegl $15,r1 # 15 digits at a time
subl2 r1,r0 # counteract acbl
jbr pattst
patmlp: bisb3 r2,$15,(r3)+ # 15
pattst: acbl $16,r1,r0,patmlp # until <= 15 left
bisb3 r2,r0,(r3)+ # rest
patzer: clrb (r3) # eo$end
rsb
scien:
bsbw fltcvt # get packed digits
scig: incl ndigit
jbs $ndfndb,flags,L23
movl $7,ndigit
L23: subl3 $17,ndigit,r0 # rounding position
ashp r0,$17,(sp),$5,ndigit,16(sp) # shift and round
bvc snovfl
# band-aid for microcode error (spurious overflow)
clrl r0 # assume even length result
jlbc ndigit,sceven # right
movl $4,r0 # odd length result
sceven: cmpv r0,$4,16(sp),$0 # top digit zero iff true overflow
bneq snovfl
# end band-aid
incl exp # rounding overflowed to 100...
subl3 $1,ndigit,r0
ashp r0,$1,pone,$0,ndigit,16(sp)
ashl $-1,ndigit,r0 # displ to last byte
bisb2 sign,16(sp)[r0] # insert sign
snovfl:
jbc $gflagb,flags,enotg # not %g format
# find trailing zeroes in packed number
ashl $-1,ndigit,r0
addl2 r3,r0 # addr of l.s.digit and sign
movl $4,r1 # bit position of digit
movl ndigit,r7 # current length of packed
jbr gtz
gtz1: xorl2 $4,r1 # position of next digit
bneq gtz # same byte
decl r0 # different byte
gtz: cmpv r1,$4,(r0),$0 # a trailing zero?
jneq gntz
sobgtr r7,gtz1
incl r7
gntz: # r7: minimum width of fraction
cmpl exp,$-4
jleq eg # small exponents use %e
subl3 r7,exp,r0
cmpl $5,r0
jleq eg # so do (w+5) <= exp
tstl r0 # rest use %f
jleq fg # did we trim too many trailing zeroes?
movl exp,r7 # yes
fg: subl3 ndigit,r7,r0
ashp r0,ndigit,16(sp),$0,r7,(sp)
movp r7,(sp),16(sp)
subl3 exp,r7,ndigit # correct ndigit for %f
jbr fnovfl
eg: subl3 ndigit,r7,r0
ashp r0,ndigit,16(sp),$0,r7,(sp)
movp r7,(sp),16(sp)
movl r7,ndigit # packed number has been trimmed
enotg:
movc3 $7,patsci,(sp)
movl $1,r6 # 1P
subl3 $1,ndigit,r0 # digits after dec.pt
bsbw patmov
editpc ndigit,16(sp),(sp),32(sp) # 32(sp)->result, r5->(end+1)
decl exp # compensate: 1 digit left of dec.pt
cvtlp exp,$2,(sp) # exponent
editpc $2,(sp),patexp,(r5)
prflt: movab 32(sp),r1
jbs $psignb,flags,prflt1
cmpb (r1)+,$'+
beql prflt1
decl r1
prflt1: skpc $' ,$63,(r1)
jbr prstr
general:
jbcs $gflagb,flags,scien
jbr scien # safety net
# convert double-floating at (ap) to 17-digit packed at (sp),
# set 'sign' and 'exp', advance ap.
fltcvt:
clrb sign
movd (ap)+,r5
jeql fzero
bgtr fpos
mnegd r5,r5
incb sign
fpos:
extzv $7,$8,r5,r2 # exponent of 2
movaw -0600(r2)[r2],r2 # unbias and mult by 3
bgeq epos
subl2 $9,r2
epos: divl2 $10,r2
bsbb expten
cmpd r0,r5
bgtr ceil
incl r2
ceil: movl r2,exp
mnegl r2,r2
cmpl r2,$29 # 10^(29+9) is all we can handle
bleq getman
muld2 ten16,r5
subl2 $16,r2
getman: addl2 $9,r2 # -ceil(log10(x)) + 9
bsbb expten
emodd r0,r4,r5,r0,r5 # (r0+r4)*r5; r0=int, r5=frac
fz1: cvtlp r0,$9,16(sp) # leading 9 digits
ashp $8,$9,16(sp),$0,$17,4(sp) # as top 9 of 17
emodd ten8,$0,r5,r0,r5
cvtlp r0,$8,16(sp) # trailing 8 digits
addp4 $8,16(sp),$17,4(sp) # combine leading and trailing
bisb2 sign,12(sp) # and insert sign
rsb
fzero: clrl r0
movl $1,exp # 0.000e+00 and 0.000 rather than 0.000e-01 and .000
jbr fz1
# return 10^r2 as a double float in r0||r1 and 8 extra bits of precision in r4
# preserve r2, r5||r6
expten:
movd $one,r0 # begin computing 10^exp10
clrl r4 # bit counter
movad ten1,r3 # table address
tstl r2
bgeq e10lp
mnegl r2,r2 # get absolute value
jbss $6,r2,e10lp # flag as negative
e10lp: jbc r4,r2,el1 # want this power?
muld2 (r3),r0 # yes
el1: addl2 $8,r3 # advance to next power
aobleq $5,r4,e10lp # through 10^32
jbcc $6,r2,el2 # correct for negative exponent
divd3 r0,$one,r0 # by taking reciprocal
mnegl r2,r2
el2: clrl r4 # 8 extra bits of precision
rsb
# powers of ten
.align 2
ten1: .word 0x4220,0,0,0
ten2: .word 0x43c8,0,0,0
ten4: .word 0x471c,0x4000,0,0
ten8: .word 0x4dbe,0xbc20,0,0
ten16: .word 0x5b0e,0x1bc9,0xbf04,0
ten32: .word 0x759d,0xc5ad,0xa82b,0x70b6

View File

@@ -0,0 +1,11 @@
!# @(#)make.sh.tconst.h.ed 1.1 92/07/30 SMI
v/^tchar/d
1,$s/=.*/;/
1,$s/^tchar/extern tchar/
1i
/* DON'T EDIT THIS FILE.
* This file was made from sh.tconst by the ed script make.sh.tconst.h.ed.
*/
.
w sh.tconst.h
q

193
bin/csh/malloc.c Normal file
View File

@@ -0,0 +1,193 @@
#ifndef lint
static char *sccsid = "@(#)malloc.c 1.1 92/07/30 SMI; from UCB 4.1 10/9/80";
#endif
#ifdef debug
#define ASSERT(p) if(!(p))botch("p");else
botch(s)
char *s;
{
printf("assertion botched: %s\n",s);
abort();
}
#else
#define ASSERT(p)
#endif
/* avoid break bug */
#ifdef pdp11
#define GRANULE 64
#else
#define GRANULE 0
#endif
/* C storage allocator
* circular first-fit strategy
* works with noncontiguous, but monotonically linked, arena
* each block is preceded by a ptr to the (pointer of)
* the next following block
* blocks are exact number of words long
* aligned to the data type requirements of ALIGN
* pointers to blocks must have BUSY bit 0
* bit in ptr is 1 for busy, 0 for idle
* gaps in arena are merely noted as busy blocks
* last block of arena (pointed to by alloct) is empty and
* has a pointer to first
* idle blocks are coalesced during space search
*
* a different implementation may need to redefine
* ALIGN, NALIGN, BLOCK, BUSY, INT
* where INT is integer type to which a pointer can be cast
*/
#define INT int
#define ALIGN int
#define NALIGN 1
#define WORD sizeof(union store)
#define BLOCK 1024 /* a multiple of WORD*/
#define BUSY 1
#define NULL 0
#define testbusy(p) ((INT)(p)&BUSY)
#define setbusy(p) (union store *)((INT)(p)|BUSY)
#define clearbusy(p) (union store *)((INT)(p)&~BUSY)
union store { union store *ptr;
ALIGN dummy[NALIGN];
int calloc; /*calloc clears an array of integers*/
};
static union store allocs[2]; /*initial arena*/
static union store *allocp; /*search ptr*/
static union store *alloct; /*arena top*/
static union store *allocx; /*for benefit of realloc*/
char *sbrk();
char *
malloc(nbytes)
unsigned nbytes;
{
register union store *p, *q;
register nw;
static temp; /*coroutines assume no auto*/
if(allocs[0].ptr==0) { /*first time*/
allocs[0].ptr = setbusy(&allocs[1]);
allocs[1].ptr = setbusy(&allocs[0]);
alloct = &allocs[1];
allocp = &allocs[0];
}
nw = (nbytes+WORD+WORD-1)/WORD;
ASSERT(allocp>=allocs && allocp<=alloct);
ASSERT(allock());
for(p=allocp; ; ) {
for(temp=0; ; ) {
if(!testbusy(p->ptr)) {
while(!testbusy((q=p->ptr)->ptr)) {
ASSERT(q>p&&q<alloct);
p->ptr = q->ptr;
}
if(q>=p+nw && p+nw>=p)
goto found;
}
q = p;
p = clearbusy(p->ptr);
if(p>q)
ASSERT(p<=alloct);
else if(q!=alloct || p!=allocs) {
ASSERT(q==alloct&&p==allocs);
return(NULL);
} else if(++temp>1)
break;
}
temp = ((nw+BLOCK/WORD)/(BLOCK/WORD))*(BLOCK/WORD);
q = (union store *)sbrk(0);
if(q+temp+GRANULE < q) {
return(NULL);
}
q = (union store *)sbrk(temp*WORD);
if((INT)q == -1) {
return(NULL);
}
ASSERT(q>alloct);
alloct->ptr = q;
if(q!=alloct+1)
alloct->ptr = setbusy(alloct->ptr);
alloct = q->ptr = q+temp-1;
alloct->ptr = setbusy(allocs);
}
found:
allocp = p + nw;
ASSERT(allocp<=alloct);
if(q>allocp) {
allocx = allocp->ptr;
allocp->ptr = p->ptr;
}
p->ptr = setbusy(allocp);
return((char *)(p+1));
}
/* freeing strategy tuned for LIFO allocation
*/
free(ap)
register char *ap;
{
register union store *p = (union store *)ap;
ASSERT(p>clearbusy(allocs[1].ptr)&&p<=alloct);
ASSERT(allock());
allocp = --p;
ASSERT(testbusy(p->ptr));
p->ptr = clearbusy(p->ptr);
ASSERT(p->ptr > allocp && p->ptr <= alloct);
}
/* realloc(p, nbytes) reallocates a block obtained from malloc()
* and freed since last call of malloc()
* to have new size nbytes, and old content
* returns new location, or 0 on failure
*/
char *
realloc(p, nbytes)
register union store *p;
unsigned nbytes;
{
register union store *q;
union store *s, *t;
register unsigned nw;
unsigned onw;
if(testbusy(p[-1].ptr))
free((char *)p);
onw = p[-1].ptr - p;
q = (union store *)malloc(nbytes);
if(q==NULL || q==p)
return((char *)q);
s = p;
t = q;
nw = (nbytes+WORD-1)/WORD;
if(nw<onw)
onw = nw;
while(onw--!=0)
*t++ = *s++;
if(q<p && q+nw>=p)
(q+(q+nw-p))->ptr = allocx;
return((char *)q);
}
#ifdef debug
allock()
{
#ifdef longdebug
register union store *p;
int x;
x = 0;
for(p= &allocs[0]; clearbusy(p->ptr) > p; p=clearbusy(p->ptr)) {
if(p==allocp)
x++;
}
ASSERT(p==alloct);
return(x==1|p==allocp);
#else
return(1);
#endif
}
#endif

40
bin/csh/param.h Normal file
View File

@@ -0,0 +1,40 @@
/* @(#)param.h 1.1 92/07/30 SMI */
/*
* Despite its name, this file has nothing in particular to
* do with <sys/param.h>. It contains definitions that the
* C version of printf needs. (The Vax version doesn't need
* this file, but instead uses an assembly language version
* of _doprnt, with printf simply arranging to call this
* version.)
*
* This business of the C shell having a private copy of
* printf is a real pain and should be fixed.
*/
/* Maximum number of digits in any integer (long) representation */
#define MAXDIGS 11
/* Convert a digit character to the corresponding number */
#define tonumber(x) ((x)-'0')
/* Convert a number between 0 and 9 to the corresponding digit */
#define todigit(x) ((x)+'0')
/* Data type for flags */
typedef char bool;
/* Maximum total number of digits in E format */
#define MAXECVT 17
/* Maximum number of digits after decimal point in F format */
#define MAXFCVT 60
/* Maximum significant figures in a floating-point number */
#define MAXFSIG 17
/* Maximum number of characters in an exponent */
#define MAXESIZ 4
/* Maximum (positive) exponent or greater */
#define MAXEXP 40

694
bin/csh/printf.c Normal file
View File

@@ -0,0 +1,694 @@
#ifndef lint
static char *sccsid = "@(#)printf.c 1.1 7/30/92";
#endif
/*
* Hacked "printf" which prints through putbyte and putchar.
* putbyte() is used to send a pure byte, which might be a part
* of a mutlibyte character, mainly for %s. A control character
* for putbyte() may be QUOTE'd meaning not to convert it to ^x
* sequence. In all other cases putchar() is used to send a character
* in tchar (== wchar_t + * optional QUOE.)
* DONT USE WITH STDIO!
* This printf has been hacked again so that it understands tchar string
* when the format specifier %t is used. Also %c has been expanded
* to take a tchar character as well as normal int.
* %t is supported in its simplest form; no width or precision will
* be understood.
* Assumption here is that sizeof(tchar)<=sizeof(int) so that tchar is
* passed as int. Otherwise, %T must be specified instead of %c to
* print a character in tchar.
*/
#include <varargs.h>
#include <values.h>
#include "sh.h" /* For tchar. */
printf (format, va_alist)
char *format;
va_dcl
{
va_list stupid;
va_start( stupid );
_print (format, &stupid);
}
/*
* Floating-point code is included or not, depending
* on whether the preprocessor variable FLOAT is 1 or 0.
*/
/*#include <ctype.h> "sh.h" defines its own version of isxxxx(). */
/*#include "param.h"... well, here is the contents of this .h file. */
/* Maximum number of digits in any integer (long) representation */
#define MAXDIGS 11
/* Convert a digit character to the corresponding number */
#define tonumber(x) ((x)-'0')
/* Convert a number between 0 and 9 to the corresponding digit */
#define todigit(x) ((x)+'0')
/* Maximum total number of digits in E format */
#define MAXECVT 17
/* Maximum number of digits after decimal point in F format */
#define MAXFCVT 60
/* Maximum significant figures in a floating-point number */
#define MAXFSIG 17
/* Maximum number of characters in an exponent */
#define MAXESIZ 4
/* Maximum (positive) exponent or greater */
#define MAXEXP 40
#define max(a,b) ((a) > (b)? (a): (b))
#define min(a,b) ((a) < (b)? (a): (b))
/* If this symbol is nonzero, allow '0' as a flag */
#define FZERO 1
#if FLOAT
/*
* System-supplied routines for floating conversion
*/
char *fcvt();
char *ecvt();
#endif
_print (format, args)
char *format;
va_list *args;
{
/* Current position in format */
char *cp;
/* Starting and ending points for value to be printed */
char *bp, *p;
tchar *tbp, *tep; /* For "%t". */
tchar tcbuf[2];/* For "%c" or "%T". */
/* Field width and precision */
int width, prec;
/* Format code */
char fcode;
/* Number of padding zeroes required on the left */
int lzero;
/* Flags - nonzero if corresponding character appears in format */
bool length; /* l */
bool fplus; /* + */
bool fminus; /* - */
bool fblank; /* blank */
bool fsharp; /* # */
#if FZERO
bool fzero; /* 0 */
#endif
/* Pointer to sign, "0x", "0X", or empty */
char *prefix;
#if FLOAT
/* Exponent or empty */
char *suffix;
/* Buffer to create exponent */
char expbuf[MAXESIZ + 1];
/* Number of padding zeroes required on the right */
int rzero;
/* The value being converted, if real */
double dval;
/* Output values from fcvt and ecvt */
int decpt, sign;
/* Scratch */
int k;
/* Values are developed in this buffer */
char buf[max (MAXDIGS, max (MAXFCVT + DMAXEXP, MAXECVT) + 1)];
#else
char buf[MAXDIGS];
#endif
/* The value being converted, if integer */
long val;
/* Set to point to a translate table for digits of whatever radix */
char *tab;
/* Work variables */
int n, hradix, lowbit;
cp = format;
/*
* The main loop -- this loop goes through one iteration
* for each ordinary character or format specification.
*/
while (*cp)
if (*cp != '%') {
/* Ordinary (non-%) character */
putbyte (*cp++);
} else {
/*
* % has been found.
* First, parse the format specification.
*/
/* Scan the <flags> */
fplus = fminus = fblank = fsharp = 0;
#if FZERO
fzero = 0;
#endif
scan: switch (*++cp) {
case '+':
fplus = 1;
goto scan;
case '-':
fminus = 1;
goto scan;
case ' ':
fblank = 1;
goto scan;
case '#':
fsharp = 1;
goto scan;
#if FZERO
case '0':
fzero = 1;
goto scan;
#endif
}
/* Scan the field width */
if (*cp == '*') {
width = va_arg (*args, int);
if (width < 0) {
width = -width;
fminus = 1;
}
cp++;
} else {
width = 0;
while (isdigit (*cp)) {
n = tonumber (*cp++);
width = width * 10 + n;
}
}
/* Scan the precision */
if (*cp == '.') {
/* '*' instead of digits? */
if (*++cp == '*') {
prec = va_arg (*args, int);
cp++;
} else {
prec = 0;
while (isdigit (*cp)) {
n = tonumber (*cp++);
prec = prec * 10 + n;
}
}
} else
prec = -1;
/* Scan the length modifier */
length = 0;
switch (*cp) {
case 'l':
length = 1;
/* No break */
case 'h':
cp++;
}
/*
* The character addressed by cp must be the
* format letter -- there is nothing left for
* it to be.
*
* The status of the +, -, #, blank, and 0
* flags are reflected in the variables
* "fplus", "fminus", "fsharp", "fblank",
* and "fzero", respectively.
* "width" and "prec" contain numbers
* corresponding to the digit strings
* before and after the decimal point,
* respectively. If there was no decimal
* point, "prec" is -1.
*
* The following switch sets things up
* for printing. What ultimately gets
* printed will be padding blanks, a prefix,
* left padding zeroes, a value, right padding
* zeroes, a suffix, and more padding
* blanks. Padding blanks will not appear
* simultaneously on both the left and the
* right. Each case in this switch will
* compute the value, and leave in several
* variables the information necessary to
* construct what is to be printed.
*
* The prefix is a sign, a blank, "0x", "0X",
* or null, and is addressed by "prefix".
*
* The suffix is either null or an exponent,
* and is addressed by "suffix".
*
* The value to be printed starts at "bp"
* and continues up to and not including "p".
*
* "lzero" and "rzero" will contain the number
* of padding zeroes required on the left
* and right, respectively. If either of
* these variables is negative, it will be
* treated as if it were zero.
*
* The number of padding blanks, and whether
* they go on the left or the right, will be
* computed on exit from the switch.
*/
lzero = 0;
prefix = "";
#if FLOAT
rzero = lzero;
suffix = prefix;
#endif
switch (fcode = *cp++) {
/*
* fixed point representations
*
* "hradix" is half the radix for the conversion.
* Conversion is unsigned unless fcode is 'd'.
* HIBITL is 1000...000 binary, and is equal to
* the maximum negative number.
* We assume a 2's complement machine
*/
case 'D':
case 'U':
length = 1;
case 'd':
case 'u':
hradix = 5;
goto fixed;
case 'O':
length = 1;
case 'o':
hradix = 4;
goto fixed;
case 'X':
case 'x':
hradix = 8;
fixed:
/* Establish default precision */
if (prec < 0)
prec = 1;
/* Fetch the argument to be printed */
if (length)
val = va_arg (*args, long);
else if (fcode == 'd')
val = va_arg (*args, int);
else
val = va_arg (*args, unsigned);
/* If signed conversion, establish sign */
if (fcode == 'd' || fcode == 'D') {
if (val < 0) {
prefix = "-";
/*
* Negate, checking in
* advance for possible
* overflow.
*/
if (val != HIBITL)
val = -val;
} else if (fplus)
prefix = "+";
else if (fblank)
prefix = " ";
}
#if FZERO
if (fzero) {
int n = width - strlen (prefix);
if (n > prec)
prec = n;
}
#endif
/* Set translate table for digits */
if (fcode == 'X')
tab = "0123456789ABCDEF";
else
tab = "0123456789abcdef";
/* Develop the digits of the value */
p = bp = buf + MAXDIGS;
while (val) {
lowbit = val & 1;
val = (val >> 1) & ~HIBITL;
*--bp = tab[val % hradix * 2 + lowbit];
val /= hradix;
}
/* Calculate padding zero requirement */
lzero = bp - p + prec;
/* Handle the # flag */
if (fsharp && bp != p)
switch (fcode) {
case 'o':
if (lzero < 1)
lzero = 1;
break;
case 'x':
prefix = "0x";
break;
case 'X':
prefix = "0X";
break;
}
break;
#if FLOAT
case 'E':
case 'e':
/*
* E-format. The general strategy
* here is fairly easy: we take
* what ecvt gives us and re-format it.
*/
/* Establish default precision */
if (prec < 0)
prec = 6;
/* Fetch the value */
dval = va_arg (*args, double);
/* Develop the mantissa */
bp = ecvt (dval,
min (prec + 1, MAXECVT),
&decpt,
&sign);
/* Determine the prefix */
e_merge:
if (sign)
prefix = "-";
else if (fplus)
prefix = "+";
else if (fblank)
prefix = " ";
/* Place the first digit in the buffer */
p = &buf[0];
*p++ = *bp != '\0'? *bp++: '0';
/* Put in a decimal point if needed */
if (prec != 0 || fsharp)
*p++ = '.';
/* Create the rest of the mantissa */
rzero = prec;
while (rzero > 0 && *bp!= '\0') {
--rzero;
*p++ = *bp++;
}
bp = &buf[0];
/* Create the exponent */
suffix = &expbuf[MAXESIZ];
*suffix = '\0';
if (dval != 0) {
n = decpt - 1;
if (n < 0)
n = -n;
while (n != 0) {
*--suffix = todigit (n % 10);
n /= 10;
}
}
/* Prepend leading zeroes to the exponent */
while (suffix > &expbuf[MAXESIZ - 2])
*--suffix = '0';
/* Put in the exponent sign */
*--suffix = (decpt > 0 || dval == 0)? '+': '-';
/* Put in the e */
*--suffix = isupper(fcode)? 'E' : 'e';
break;
case 'f':
/*
* F-format floating point. This is
* a good deal less simple than E-format.
* The overall strategy will be to call
* fcvt, reformat its result into buf,
* and calculate how many trailing
* zeroes will be required. There will
* never be any leading zeroes needed.
*/
/* Establish default precision */
if (prec < 0)
prec = 6;
/* Fetch the value */
dval = va_arg (*args, double);
/* Do the conversion */
bp = fcvt (dval,
min (prec, MAXFCVT),
&decpt,
&sign);
/* Determine the prefix */
f_merge:
if (sign && decpt > -prec &&
*bp != '\0' && *bp != '0')
prefix = "-";
else if (fplus)
prefix = "+";
else if (fblank)
prefix = " ";
/* Initialize buffer pointer */
p = &buf[0];
/* Emit the digits before the decimal point */
n = decpt;
k = 0;
if (n <= 0)
*p++ = '0';
else
do if (*bp == '\0' || k >= MAXFSIG)
*p++ = '0';
else {
*p++ = *bp++;
++k;
}
while (--n != 0);
/* Decide whether we need a decimal point */
if (fsharp || prec > 0)
*p++ = '.';
/* Digits (if any) after the decimal point */
n = min (prec, MAXFCVT);
rzero = prec - n;
while (--n >= 0)
if (++decpt <= 0
|| *bp == '\0'
|| k >= MAXFSIG)
*p++ = '0';
else {
*p++ = *bp++;
++k;
}
bp = &buf[0];
break;
case 'G':
case 'g':
/*
* g-format. We play around a bit
* and then jump into e or f, as needed.
*/
/* Establish default precision */
if (prec < 0)
prec = 6;
/* Fetch the value */
dval = va_arg (*args, double);
/* Do the conversion */
bp = ecvt (dval,
min (prec, MAXECVT),
&decpt,
&sign);
if (dval == 0)
decpt = 1;
k = prec;
if (!fsharp) {
n = strlen (bp);
if (n < k)
k = n;
while (k >= 1 && bp[k-1] == '0')
--k;
}
if (decpt < -3 || decpt > prec) {
prec = k - 1;
goto e_merge;
} else {
prec = k - decpt;
goto f_merge;
}
#endif
case 'c':
#ifdef sizeof(int)>=sizeof(tchar)
/* A tchar arg is passed as int so we used the normal %c to specify
* such an arugumetn.
*/ tcbuf[0] = va_arg (*args, int);
tbp = &tcbuf[0];
tep = tbp + 1;
fcode='t'; /* Fake the rest of code. */
break;
#else
/* We would have to invent another new format speficier such as "%T" to
* take a tchar arg. Let's worry about when that time comes.
*/ /* Following code take care of a char arg
* only.
*/
buf[0] = va_arg (*args, int);
bp = &buf[0];
p = bp + 1;
break;
case 'T': /* Corresponding arg is tchar. */
tcbuf[0] = va_arg (*args, tchar);
tbp = &tcbuf[0];
tep = tbp + 1;
fcode='t'; /* Fake the rest of code. */
break;
#endif
case 's':
bp = va_arg (*args, char *);
if (bp == 0) {
nullstr: bp = "(null)";
p = bp + strlen("(null)");
break;
}
if (prec < 0)
prec = MAXINT;
for (n=0; *bp++ != '\0' && n < prec; n++);
p = --bp;
bp -= n;
break;
case 't': /* Special format specifier "%t" tells
* printf() to print char strings written
* as tchar string.
*/
tbp = va_arg (*args, tchar *);
if (tbp == 0) {
fcode='s';/* Act as if it were %s. */
goto nullstr;
}
if (prec < 0)
prec = MAXINT;
for (n=0; *tbp++ != 0 && n < prec; n++);
tep = --tbp;
tbp -= n;
/* Just to make the following padding
* calculation not to go very crazy...
*/
bp = NULL;
p = bp+n;
break;
case '\0':
cp--;
break;
/* case '%': */
default:
p = bp = &fcode;
p++;
break;
}
if (fcode != '\0') {
/* Calculate number of padding blanks */
int nblank;
nblank = width
#if FLOAT
- (rzero < 0? 0: rzero)
- strlen (suffix)
#endif
- (p - bp)
- (lzero < 0? 0: lzero)
- strlen (prefix);
/* Blanks on left if required */
if (!fminus)
while (--nblank >= 0)
putchar (' ');
/* Prefix, if any */
while (*prefix != '\0')
putchar (*prefix++);
/* Zeroes on the left */
while (--lzero >= 0)
putchar ('0');
/* The value itself */
if(fcode == 't'){/* %t is special. */
while (tbp < tep)
putchar (*tbp++);
}else{/* For rest of the cases. */
while (bp < p)
putbyte (*bp++);
}
#if FLOAT
/* Zeroes on the right */
while (--rzero >= 0)
putchar ('0');
/* The suffix */
while (*suffix != '\0')
putchar (*suffix++);
#endif
/* Blanks on the right if required */
if (fminus)
while (--nblank >= 0)
putchar (' ');
}
}
}

44
bin/csh/printf.c.vax Normal file
View File

@@ -0,0 +1,44 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)printf.c.vax 1.1 92/07/30 SMI; from UCB 5.2 6/6/85";
#endif
/*
* Hacked "printf" which prints through putchar.
* DONT USE WITH STDIO!
*/
printf(fmt, args)
char *fmt;
{
_doprnt(fmt, &args, 0);
}
_strout(count, string, adjust, foo, fillch)
register char *string;
register int count;
int adjust;
register struct { int a[6]; } *foo;
{
if (foo != 0)
abort();
while (adjust < 0) {
if (*string=='-' && fillch=='0') {
putchar(*string++);
count--;
}
putchar(fillch);
adjust++;
}
while (--count>=0)
putchar(*string++);
while (adjust) {
putchar(fillch);
adjust--;
}
}

458
bin/csh/sh.8bit.c Normal file
View File

@@ -0,0 +1,458 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.8bit.c 1.1 92/07/30 SMI; from SUN 5/5/88";
#endif
#include "sh.h"
#include <stdio.h>
#include <sys/file.h>
#include <errno.h>
extern int errno;
#define IN_INIT 0x0000
#define IN_SQUOTE 0x0001
#define IN_DQUOTE 0x0002
#define QUOTE_NEXT 0x0004
#define SLASH '\\'
/*
* set bit buffer
*/
set_bitbuf(s, p)
register char *s;
register char *p;
{
int status = 0;
int quote_next = 0;
int cnt;
/*
* First, let me set temporary buffer.
*/
while (*s) {
switch (*s) {
case '\\':
switch (status) {
case IN_SQUOTE:
*p++ = 1;
break;
case IN_DQUOTE:
*p++ = 1;
break;
case QUOTE_NEXT:
*p++ = 1;
status = 0;
break;
default:
*p++ = 0;
status = QUOTE_NEXT;
break;
}
break;
case '\'':
switch (status) {
case IN_SQUOTE:
/*
* end of single quote
*/
*p++ = 0;
status = 0;
break;
case IN_DQUOTE:
*p++ = 0;
break;
case QUOTE_NEXT:
*p++ = 1;
status = 0;
break;
default:
/*
* start single quote
*/
status = IN_SQUOTE;
*p++ = 0;
}
break;
case '"':
switch (status) {
case IN_SQUOTE:
*p++ = 1;
break;
case IN_DQUOTE:
/*
* end of double quote
*/
*p++ = 0;
status = 0;
break;
case QUOTE_NEXT:
*p++ = 1;
status = 0;
break;
default:
*p++ = 0;
status = IN_DQUOTE;
break;
}
break;
default:
/*
* non-special character
*/
switch (status) {
case IN_SQUOTE:
*p++ = 1;
break;
case IN_DQUOTE:
if (ISglob(*s) && (*s != '`'))
*p++ = 1;
else
*p++ = 0;
break;
case QUOTE_NEXT:
*p++ = 1;
status = 0;
break;
default:
*p++ = 0;
break;
}
break;
}
++s;
}
}
/*
* set bit array
*/
set_bitarray(from, to)
char *from;
register char *to;
{
int len;
register char *p;
char buf[BUFSIZ];
set_bitbuf(from, buf);
p = buf;
for (len = 0; len < strlen(from); len++)
*to++ = *p++;
}
/*
* different any
*/
any8(c, s)
register int c;
register char *s;
{
char buf[BUFSIZ];
register char *pp;
if (!s)
return(0);
set_bitbuf(s, buf);
pp = buf;
while (*s)
if (*s++ == c && *pp++ == 0) {
return(1);
}
return(0);
}
/*
* trim off back slash
*/
trim_slash_dbg(t)
register char **t;
{
register char *p;
#ifdef DBG
dprintf("TRIM_SLASH\n");
while (p = *t++) {
dprintf(p);
dprintf("\n");
}
dprintf("OUT TRIM_SLASH\n");
#endif
}
/*
* trim off back slash
*/
trim_slash(t)
register char **t;
{
register char *s;
char buffer[BUFSIZ];
int status = 0;
char *p;
char *s1;
while (s = *t) {
p = buffer;
s1 = s;
while (*s) {
switch (*s) {
case '\\':
switch (status) {
case IN_SQUOTE:
*p++ = *s;
break;
case IN_DQUOTE:
*p++ = *s;
break;
case QUOTE_NEXT:
*p++ = *s;
status = 0;
break;
default:
status = QUOTE_NEXT;
break;
}
break;
case '\'':
switch (status) {
case IN_SQUOTE:
/*
* end of single quote
*/
status = 0;
break;
case IN_DQUOTE:
*p++ = *s;
break;
case QUOTE_NEXT:
*p++ = *s;
status = 0;
break;
default:
/*
* start single quote
*/
status = IN_SQUOTE;
break;
}
break;
case '"':
switch (status) {
case IN_SQUOTE:
*p++ = *s;
break;
case IN_DQUOTE:
/*
* end of double quote
*/
status = 0;
break;
case QUOTE_NEXT:
*p++ = *s;
status = 0;
break;
default:
status = IN_DQUOTE;
break;
}
break;
default:
/*
* non-special character
*/
switch (status) {
case IN_SQUOTE:
*p++ = *s;
break;
case IN_DQUOTE:
*p++ = *s;
break;
case QUOTE_NEXT:
*p++ = *s;
status = 0;
break;
default:
*p++ = *s;
break;
}
break;
}
++s;
}
/*
* fix real string here
*/
*p = 0;
#ifdef DBG
dprintf("IN trim_slash\n");
dprintf("BEFORE - "); dprintf(s1); dprintf("\n");
dprintf("AFTER - "); dprintf(buffer); dprintf("\n");
#endif
strcpy(*t, buffer);
t++;
}
}
/*
* set_map and init_map_status
*/
static int map_status = 0; /* This is used only in set_map & init_map_status */
static int pre_map_status = 0; /* save the previous one */
/*
* Give me more task !
*/
init_map_status()
{
map_status = IN_INIT;
pre_map_status = IN_INIT;
}
/*
* restore previous status
*/
fix_map_status()
{
map_status = pre_map_status;
}
/*
* Lot's of brother/sister's
*/
set_map(map, c)
char *map;
char c;
{
pre_map_status = map_status;
switch (c) {
case '\\':
switch (map_status) {
case IN_SQUOTE:
*map = 1;
break;
case IN_DQUOTE:
*map = 1;
break;
case QUOTE_NEXT:
*map = 1;
map_status = IN_INIT;
break;
case IN_INIT:
default:
*map = 1;
map_status = QUOTE_NEXT;
break;
}
break;
case '\'':
switch (map_status) {
case IN_SQUOTE:
/*
* end of single quote
*/
*map = 1;
map_status = IN_INIT;
break;
case IN_DQUOTE:
*map = 0;
break;
case QUOTE_NEXT:
*map = 1;
map_status = IN_INIT;
break;
case IN_INIT:
default:
/*
* start single quote
*/
map_status = IN_SQUOTE;
*map = 1;
}
break;
case '"':
switch (map_status) {
case IN_SQUOTE:
*map = 1;
break;
case IN_DQUOTE:
/*
* end of double quote
*/
*map = 0;
map_status = IN_INIT;
break;
case QUOTE_NEXT:
*map = 1;
map_status = IN_INIT;
break;
case IN_INIT:
default:
*map = 0;
map_status = IN_DQUOTE;
break;
}
break;
default:
/*
* non-special character
*/
switch (map_status) {
case IN_SQUOTE:
*map = 1;
break;
case IN_DQUOTE:
if (ISglob(c) && (c != '`'))
*map = 1;
else
*map = 0;
break;
case QUOTE_NEXT:
*map = 1;
map_status = IN_INIT;
break;
case IN_INIT:
default:
*map = 0;
break;
}
break;
}
}
/*
* check_me
* return 1 -- if the next character will be quoted
* 0 -- otherwise
*/
check_me()
{
int ret = 0;
switch (map_status) {
case IN_SQUOTE:
ret = 1;
break;
case IN_DQUOTE:
ret = 0;
break;
case QUOTE_NEXT:
ret = 1;
break;
case IN_INIT:
default:
ret = 0;
break;
}
return(ret);
}

1064
bin/csh/sh.c Normal file

File diff suppressed because it is too large Load Diff

109
bin/csh/sh.char.c Normal file
View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.char.c 1.1 92/07/30 SMI; from UCB 5.3 3/29/86";
#endif
#include "sh.char.h"
unsigned short _cmap[128] = {
/* nul soh stx etx */
0, 0, 0, 0,
/* eot enq ack bel */
0, 0, 0, 0,
/* bs ht nl vt */
0, _SP|_META, _NL|_META, 0,
/* np cr so si */
0, 0, 0, 0,
/* dle dc1 dc2 dc3 */
0, 0, 0, 0,
/* dc4 nak syn etb */
0, 0, 0, 0,
/* can em sub esc */
0, 0, 0, 0,
/* fs gs rs us */
0, 0, 0, 0,
/* sp ! " # */
_SP|_META, 0, _Q, _META,
/* $ % & ' */
_DOL, 0, _META, _Q,
/* ( ) * + */
_META, _META, _GLOB, 0,
/* , - . / */
0, 0, 0, 0,
/* 0 1 2 3 */
_DIG, _DIG, _DIG, _DIG,
/* 4 5 6 7 */
_DIG, _DIG, _DIG, _DIG,
/* 8 9 : ; */
_DIG, _DIG, 0, _META,
/* < = > ? */
_META, 0, _META, _GLOB,
/* @ A B C */
0, _LET, _LET, _LET,
/* D E F G */
_LET, _LET, _LET, _LET,
/* H I J K */
_LET, _LET, _LET, _LET,
/* L M N O */
_LET, _LET, _LET, _LET,
/* P Q R S */
_LET, _LET, _LET, _LET,
/* T U V W */
_LET, _LET, _LET, _LET,
/* X Y Z [ */
_LET, _LET, _LET, _GLOB,
/* \ ] ^ _ */
_ESC, 0, 0, _LET,
/* ` a b c */
_Q1|_GLOB, _LET, _LET, _LET,
/* d e f g */
_LET, _LET, _LET, _LET,
/* h i j k */
_LET, _LET, _LET, _LET,
/* l m n o */
_LET, _LET, _LET, _LET,
/* p q r s */
_LET, _LET, _LET, _LET,
/* t u v w */
_LET, _LET, _LET, _LET,
/* x y z { */
_LET, _LET, _LET, _GLOB,
/* | } ~ del */
_META, 0, 0, 0,
};

57
bin/csh/sh.char.h Normal file
View File

@@ -0,0 +1,57 @@
/* @(#)sh.char.h 1.1 92/07/30 SMI; from UCB 5.3 3/29/86 */
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
/*
* Macros to classify characters.
*/
#ifdef MBCHAR
#include <wctype.h>
#define isauxspZ (!isascii(Z)&&!(Z&QUOTE)&&iswspace(Z))
#define isauxsp(c) (Z=((unsigned)(c)), isauxspZ)
/* Regocnizes non-ASCII space characters. */
#else
#include <ctype.h>
/* macros of macros to reduce further #ifdef MBCHAR later. Please be patient!*/
#define iswdigit(c) isdigit(c)
#define iswalpha(c) isalpha(c)
#define isphonogram(c) 0
#define isideogram(c) 0
#define isauxsp(c) 0
#define isauxspZ 0
#endif
extern unsigned short _cmap[];/* Defined in sh.char.c */
unsigned int Z; /* A place to save macro arg to avoid side-effect!*/
#define _Q 0x01 /* '" */
#define _Q1 0x02 /* ` */
#define _SP 0x04 /* space and tab */
#define _NL 0x08 /* \n */
#define _META 0x10 /* lex meta characters, sp #'`";&<>()|\t\n */
#define _GLOB 0x20 /* glob characters, *?{[` */
#define _ESC 0x40 /* \ */
#define _DOL 0x80 /* $ */
#define _DIG 0x100 /* 0-9 */
#define _LET 0x200 /* a-z, A-Z, _ NO LONGER OF REAL USE. */
#define cmapZ(bits) (isascii(Z)?(_cmap[Z] & (bits)):0)
#define cmap(c, bits) (Z=((unsigned)(c)), cmapZ(bits))
#define isglob(c) cmap(c, _GLOB)
#define ismeta(c) cmap(c, _META)
#define digit(c) cmap(c, _DIG)
#define issp(c) (Z=((unsigned)(c)), cmapZ( _SP)||isauxspZ)
/*WAS isspace(c)*/
#define isspnl(c) (Z=((unsigned)(c)), cmapZ( _SP|_NL)||isauxspZ)
#define letter(c) (Z=((unsigned)(c)), iswalpha(Z)||((Z)=='_')\
||isphonogram(Z)||isideogram(Z))
#define alnum(c) (Z=((unsigned)(c)), iswalpha(Z)||((Z)=='_')\
||iswdigit(Z)||isphonogram(Z)||isideogram(Z))

52
bin/csh/sh.debug.c Normal file
View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.debug.c 1.1 92/07/30 SMI; from UCB 5.4 3/29/86";
#endif
#include "sh.h"
#include <sgtty.h>
#ifdef TRACE
#include <stdio.h>
FILE *trace;
/*
* Trace routines
*/
#define TRACEFILE "/tmp/trace.XXXXXX"
/*
* Initialie trace file.
* Called from main.
*/
trace_init()
{
extern char *mktemp();
char name[128];
char *p;
strcpy(name, TRACEFILE);
p = mktemp(name);
trace = fopen(p, "w");
}
/*
* write message to trace file
*/
/*VARARGS1*/
tprintf(fmt,a,b,c,d,e,f,g,h,i,j)
char *fmt;
{
if (trace) {
fprintf(trace, fmt, a,b,c,d,e,f,g,h,i,j);
fflush(trace);
}
}
#endif

612
bin/csh/sh.dir.c Normal file
View File

@@ -0,0 +1,612 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.dir.c 1.1 92/07/30 SMI; from UCB 5.3 6/11/85";
#endif
#include "sh.h"
#include "sh.dir.h"
#include "sh.tconst.h"
/*
* C Shell - directory management
*/
struct directory *dfind();
tchar *dfollow();
tchar *dcanon();
struct directory dhead; /* "head" of loop */
int printd; /* force name to be printed */
static tchar *fakev[] = { S_dirs, NOSTR };
/*
* dinit - initialize current working directory
*/
dinit(hp)
tchar *hp;
{
register tchar *cp;
register struct directory *dp;
tchar path[MAXPATHLEN];
#ifdef TRACE
tprintf("TRACE- dinit()\n");
#endif
if (loginsh && hp)
cp = hp;
else {
cp = getwd_(path);
if (cp == NULL) {
haderr = 1;
printf ("%t\n", path);
exit(1);
}
}
dp = (struct directory *)calloc(sizeof (struct directory), 1);
dp->di_name = savestr(cp);
dp->di_count = 0;
dhead.di_next = dhead.di_prev = dp;
dp->di_next = dp->di_prev = &dhead;
printd = 0;
dnewcwd(dp);
}
/*
* dodirs - list all directories in directory loop
*/
dodirs(v)
tchar **v;
{
register struct directory *dp;
bool lflag;
tchar *hp = value(S_home);
#ifdef TRACE
tprintf("TRACE- dodirs()\n");
#endif
if (*hp == '\0')
hp = NOSTR;
if (*++v != NOSTR)
if (eq(*v, S_MINl /* "-l" */) && *++v == NOSTR)
lflag = 1;
else
error("Usage: dirs [ -l ]");
else
lflag = 0;
dp = dcwd;
do {
if (dp == &dhead)
continue;
if (!lflag && hp != NOSTR) {
dtildepr(hp, dp->di_name);
} else
printf("%t", dp->di_name);
printf(" ");
} while ((dp = dp->di_prev) != dcwd);
printf("\n");
}
dtildepr(home, dir)
register tchar *home, *dir;
{
#ifdef TRACE
tprintf("TRACE- dtildepr()\n");
#endif
if (!eq(home, S_SLASH /* "/" */) && prefix(home, dir))
printf("~%t", dir + strlen_(home));
else
printf("%t", dir);
}
/*
* dochngd - implement chdir command.
*/
dochngd(v)
tchar **v;
{
register tchar *cp;
register struct directory *dp;
#ifdef TRACE
tprintf("TRACE- dochngd()\n");
#endif
printd = 0;
if (*++v == NOSTR) {
if ((cp = value(S_home)) == NOSTR || *cp == 0)
bferr("No home directory");
if (chdir_(cp) < 0)
bferr("Can't change to home directory");
cp = savestr(cp);
} else if ((dp = dfind(*v)) != 0) {
printd = 1;
if (chdir_(dp->di_name) < 0)
Perror(dp->di_name);
dcwd->di_prev->di_next = dcwd->di_next;
dcwd->di_next->di_prev = dcwd->di_prev;
goto flushcwd;
} else
cp = dfollow(*v);
dp = (struct directory *)calloc(sizeof (struct directory), 1);
dp->di_name = cp;
dp->di_count = 0;
dp->di_next = dcwd->di_next;
dp->di_prev = dcwd->di_prev;
dp->di_prev->di_next = dp;
dp->di_next->di_prev = dp;
flushcwd:
dfree(dcwd);
dnewcwd(dp);
}
/*
* dfollow - change to arg directory; fall back on cdpath if not valid
*/
tchar *
dfollow(cp)
register tchar *cp;
{
register tchar *dp;
struct varent *c;
#ifdef TRACE
tprintf("TRACE- dfollow()\n");
#endif
cp = globone(cp);
if (chdir_(cp) >= 0)
goto gotcha;
/*
* Try interpreting wrt successive components of cdpath.
*/
if (cp[0] != '/'
&& !prefix(S_DOTSLA /* "./" */, cp)
&& !prefix(S_DOTDOTSLA /* "../" */, cp)
&& (c = adrof(S_cdpath))) {
tchar **cdp;
register tchar *p;
tchar buf[MAXPATHLEN];
for (cdp = c->vec; *cdp; cdp++) {
for (dp = buf, p = *cdp; *dp++ = *p++;)
;
dp[-1] = '/';
for (p = cp; *dp++ = *p++;)
;
if (chdir_(buf) >= 0) {
printd = 1;
xfree(cp);
cp = savestr(buf);
goto gotcha;
}
}
}
/*
* Try dereferencing the variable named by the argument.
*/
dp = value(cp);
if ((dp[0] == '/' || dp[0] == '.') && chdir_(dp) >= 0) {
xfree(cp);
cp = savestr(dp);
printd = 1;
goto gotcha;
}
xfree(cp); /* XXX, use after free */
Perror(cp);
gotcha:
if (*cp != '/') {
register tchar *p, *q;
int cwdlen;
/*
* All in the name of efficiency?
*/
for (p = dcwd->di_name; *p++;)
;
if ((cwdlen = p - dcwd->di_name - 1) == 1) /* root */
cwdlen = 0;
for (p = cp; *p++;)
;
dp = (tchar *)xalloc((unsigned) (cwdlen + (p - cp) + 1)*sizeof (tchar));
for (p = dp, q = dcwd->di_name; *p++ = *q++;)
;
if (cwdlen)
p[-1] = '/';
else
p--; /* don't add a / after root */
for (q = cp; *p++ = *q++;)
;
xfree(cp);
cp = dp;
dp += cwdlen;
} else
dp = cp;
return dcanon(cp, dp);
}
/*
* dopushd - push new directory onto directory stack.
* with no arguments exchange top and second.
* with numeric argument (+n) bring it to top.
*/
dopushd(v)
tchar **v;
{
register struct directory *dp;
#ifdef TRACE
tprintf("TRACE- dopushd()\n");
#endif
printd = 1;
if (*++v == NOSTR) {
if ((dp = dcwd->di_prev) == &dhead)
dp = dhead.di_prev;
if (dp == dcwd)
bferr("No other directory");
if (chdir_(dp->di_name) < 0)
Perror(dp->di_name);
dp->di_prev->di_next = dp->di_next;
dp->di_next->di_prev = dp->di_prev;
dp->di_next = dcwd->di_next;
dp->di_prev = dcwd;
dcwd->di_next->di_prev = dp;
dcwd->di_next = dp;
} else if (dp = dfind(*v)) {
if (chdir_(dp->di_name) < 0)
Perror(dp->di_name);
} else {
register tchar *cp;
cp = dfollow(*v);
dp = (struct directory *)calloc(sizeof (struct directory), 1);
dp->di_name = cp;
dp->di_count = 0;
dp->di_prev = dcwd;
dp->di_next = dcwd->di_next;
dcwd->di_next = dp;
dp->di_next->di_prev = dp;
}
dnewcwd(dp);
}
/*
* dfind - find a directory if specified by numeric (+n) argument
*/
struct directory *
dfind(cp)
register tchar *cp;
{
register struct directory *dp;
register int i;
register tchar *ep;
#ifdef TRACE
tprintf("TRACE- dfind()\n");
#endif
if (*cp++ != '+')
return (0);
for (ep = cp; digit(*ep); ep++)
continue;
if (*ep)
return (0);
i = getn(cp);
if (i <= 0)
return (0);
for (dp = dcwd; i != 0; i--) {
if ((dp = dp->di_prev) == &dhead)
dp = dp->di_prev;
if (dp == dcwd)
bferr("Directory stack not that deep");
}
return (dp);
}
/*
* dopopd - pop a directory out of the directory stack
* with a numeric argument just discard it.
*/
dopopd(v)
tchar **v;
{
register struct directory *dp, *p;
#ifdef TRACE
tprintf("TRACE- dopopd()\n");
#endif
printd = 1;
if (*++v == NOSTR)
dp = dcwd;
else if ((dp = dfind(*v)) == 0)
bferr("Invalid argument");
if (dp->di_prev == &dhead && dp->di_next == &dhead)
bferr("Directory stack empty");
if (dp == dcwd) {
if ((p = dp->di_prev) == &dhead)
p = dhead.di_prev;
if (chdir_(p->di_name) < 0)
Perror(p->di_name);
}
dp->di_prev->di_next = dp->di_next;
dp->di_next->di_prev = dp->di_prev;
if (dp == dcwd)
dnewcwd(p);
else
dodirs(fakev);
dfree(dp);
}
/*
* dfree - free the directory (or keep it if it still has ref count)
*/
dfree(dp)
register struct directory *dp;
{
#ifdef TRACE
tprintf("TRACE- dfree()\n");
#endif
if (dp->di_count != 0)
dp->di_next = dp->di_prev = 0;
else
xfree(dp->di_name), xfree( (tchar *)dp);
}
/*
* dcanon - canonicalize the pathname, removing excess ./ and ../ etc.
* We are of course assuming that the file system is standardly
* constructed (always have ..'s, directories have links).
*
* If the hardpaths shell variable is set, resolve the
* resulting pathname to contain no symbolic link components.
*/
tchar *
dcanon(cp, p)
register tchar *cp, *p;
{
register tchar *sp; /* rightmost component currently under
consideration */
register tchar *p1, /* general purpose */
*p2;
bool slash, dotdot, hardpaths;
#ifdef TRACE
tprintf("TRACE- dcannon()\n");
#endif
if (*cp != '/')
abort();
if (hardpaths = (adrof(S_hardpaths) != NULL)) {
/*
* Be paranoid: don't trust the initial prefix
* to be symlink-free.
*/
p = cp;
}
/*
* Loop invariant: cp points to the overall path start,
* p to its as yet uncanonicalized trailing suffix.
*/
while (*p) { /* for each component */
sp = p; /* save slash address */
while (*++p == '/') /* flush extra slashes */
;
if (p != ++sp)
for (p1 = sp, p2 = p; *p1++ = *p2++;)
;
p = sp; /* save start of component */
slash = 0;
while (*++p) /* find next slash or end of path */
if (*p == '/') {
slash = 1;
*p = '\0';
break;
}
if (*sp == '\0') {
/* component is null */
if (--sp == cp) /* if path is one tchar (i.e. /) */
break;
else
*sp = '\0';
continue;
}
if (sp[0] == '.' && sp[1] == '\0') {
/* Squeeze out component consisting of "." */
if (slash) {
for (p1 = sp, p2 = p + 1; *p1++ = *p2++;)
;
p = --sp;
} else if (--sp != cp)
*sp = '\0';
continue;
}
/*
* At this point we have a path of the form "x/yz",
* where "x" is null or rooted at "/", "y" is a single
* component, and "z" is possibly null. The pointer cp
* points to the start of "x", sp to the start of "y",
* and p to the beginning of "z", which has been forced
* to a null.
*/
/*
* Process symbolic link component. Provided that either
* the hardpaths shell variable is set or "y" is really
* ".." we replace the symlink with its contents. The
* second condition for replacement is necessary to make
* the command "cd x/.." produce the same results as the
* sequence "cd x; cd ..".
*
* Note that the two conditions correspond to different
* potential symlinks. When hardpaths is set, we must
* check "x/y"; otherwise, when "y" is known to be "..",
* we check "x".
*/
dotdot = sp[0] == '.' && sp[1] == '.' && sp[2] == '\0';
if (hardpaths || dotdot) {
tchar link[MAXPATHLEN];
int cc;
tchar *newcp;
/*
* Isolate the end of the component that is to
* be checked for symlink-hood.
*/
sp--;
if (! hardpaths)
*sp = '\0';
/*
* See whether the component is really a symlink by
* trying to read it. If the read succeeds, it is.
*/
if ((hardpaths || sp > cp) &&
(cc = readlink_(cp, link, MAXPATHLEN)) >= 0) {
/*
* readlink_ put null, so we don't need this.
*/
/* link[cc] = '\0'; */
/* Restore path. */
if (slash)
*p = '/';
/*
* Point p at the start of the trailing
* path following the symlink component.
* It's already there is hardpaths is set.
*/
if (! hardpaths) {
/* Restore path as well. */
*(p = sp) = '/';
}
/*
* Find length of p.
*/
for (p1 = p; *p1++;)
;
if (*link != '/') {
/*
* Relative path: replace the symlink
* component with its value. First,
* set sp to point to the slash at
* its beginning. If hardpaths is
* set, this is already the case.
*/
if (! hardpaths) {
while (*--sp != '/')
;
}
/*
* Terminate the leading part of the
* path, including trailing slash.
*/
sp++;
*sp = '\0';
/*
* New length is: "x/" + link + "z"
*/
p1 = newcp = (tchar *)xalloc((unsigned)
((sp - cp) + cc + (p1 - p))*sizeof (tchar));
/*
* Copy new path into newcp
*/
for (p2 = cp; *p1++ = *p2++;)
;
for (p1--, p2 = link; *p1++ = *p2++;)
;
for (p1--, p2 = p; *p1++ = *p2++;)
;
/*
* Restart canonicalization at
* expanded "/y".
*/
p = sp - cp - 1 + newcp;
} else {
/*
* New length is: link + "z"
*/
p1 = newcp = (tchar *)xalloc((unsigned)
(cc + (p1 - p))*sizeof (tchar));
/*
* Copy new path into newcp
*/
for (p2 = link; *p1++ = *p2++;)
;
for (p1--, p2 = p; *p1++ = *p2++;)
;
/*
* Restart canonicalization at beginning
*/
p = newcp;
}
xfree(cp);
cp = newcp;
continue; /* canonicalize the link */
}
/* The component wasn't a symlink after all. */
if (! hardpaths)
*sp = '/';
}
if (dotdot) {
if (sp != cp)
while (*--sp != '/')
;
if (slash) {
for (p1 = sp + 1, p2 = p + 1; *p1++ = *p2++;)
;
p = sp;
} else if (cp == sp)
*++sp = '\0';
else
*sp = '\0';
continue;
}
if (slash)
*p = '/';
}
return cp;
}
/*
* dnewcwd - make a new directory in the loop the current one
* and export its name to the PWD environment variable.
*/
dnewcwd(dp)
register struct directory *dp;
{
#ifdef TRACE
tprintf("TRACE- dnewcwd()\n");
#endif
dcwd = dp;
#ifdef notdef
/*
* If we have a fast version of getwd available
* and hardpaths is set, it would be reasonable
* here to verify that dcwd->di_name really does
* name the current directory. Later...
*/
#endif notdef
set(S_cwd, savestr(dcwd->di_name));
setenv(S_PWD, dcwd->di_name);
if (printd)
dodirs(fakev);
}

18
bin/csh/sh.dir.h Normal file
View File

@@ -0,0 +1,18 @@
/* @(#)sh.dir.h 1.1 92/07/30 SMI; from UCB 5.2 6/6/85 */
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
/*
* Structure for entries in directory stack.
*/
struct directory {
struct directory *di_next; /* next in loop */
struct directory *di_prev; /* prev in loop */
unsigned short *di_count; /* refcount of processes */
tchar *di_name; /* actual name */
};
struct directory *dcwd; /* the one we are in now */

737
bin/csh/sh.dol.c Normal file
View File

@@ -0,0 +1,737 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.dol.c 1.1 92/07/30 SMI; from UCB 5.3 3/29/86";
#endif
#include "sh.h"
#include "sh.tconst.h"
/*
* C shell
*/
/*
* These routines perform variable substitution and quoting via ' and ".
* To this point these constructs have been preserved in the divided
* input words. Here we expand variables and turn quoting via ' and " into
* QUOTE bits on characters (which prevent further interpretation).
* If the `:q' modifier was applied during history expansion, then
* some QUOTEing may have occurred already, so we dont "trim()" here.
*/
int Dpeekc, Dpeekrd; /* Peeks for DgetC and Dreadc */
tchar *Dcp, **Dvp; /* Input vector for Dreadc */
#define DEOF -1
#define unDgetC(c) Dpeekc = c
#define QUOTES (_Q|_Q1|_ESC) /* \ ' " ` */
/*
* The following variables give the information about the current
* $ expansion, recording the current word position, the remaining
* words within this expansion, the count of remaining words, and the
* information about any : modifier which is being applied.
*/
tchar *dolp; /* Remaining chars from this word */
tchar **dolnxt; /* Further words */
int dolcnt; /* Count of further words */
tchar dolmod; /* : modifier character */
int dolmcnt; /* :gx -> 10000, else 1 */
/*
* Fix up the $ expansions and quotations in the
* argument list to command t.
*/
Dfix(t)
register struct command *t;
{
register tchar **pp;
register tchar *p;
#ifdef TRACE
tprintf("TRACE- Dfix()\n");
#endif
if (noexec)
return;
/* Note that t_dcom isn't trimmed thus !...:q's aren't lost */
for (pp = t->t_dcom; p = *pp++;)
while (*p)
if (cmap(*p++, _DOL|QUOTES)) { /* $, \, ', ", ` */
Dfix2(t->t_dcom); /* found one */
blkfree(t->t_dcom);
t->t_dcom = gargv;
gargv = 0;
return;
}
}
/*
* $ substitute one word, for i/o redirection
*/
tchar *
Dfix1(cp)
register tchar *cp;
{
tchar *Dv[2];
#ifdef TRACE
tprintf("TRACE- Dfix1()\n");
#endif
if (noexec)
return (0);
Dv[0] = cp; Dv[1] = NOSTR;
Dfix2(Dv);
if (gargc != 1) {
setname(cp);
bferr("Ambiguous");
}
cp = savestr(gargv[0]);
blkfree(gargv), gargv = 0;
return (cp);
}
/*
* Subroutine to do actual fixing after state initialization.
*/
Dfix2(v)
tchar **v;
{
tchar *agargv[GAVSIZ];
#ifdef TRACE
tprintf("TRACE- Dfix2()\n");
#endif
ginit(agargv); /* Initialize glob's area pointers */
Dvp = v; Dcp = S_ /* "" */;/* Setup input vector for Dreadc */
unDgetC(0); unDredc(0); /* Clear out any old peeks (at error) */
dolp = 0; dolcnt = 0; /* Clear out residual $ expands (...) */
while (Dword())
continue;
gargv = copyblk(gargv);
}
/*
* Get a word. This routine is analogous to the routine
* word() in sh.lex.c for the main lexical input. One difference
* here is that we don't get a newline to terminate our expansion.
* Rather, DgetC will return a DEOF when we hit the end-of-input.
*/
Dword()
{
register int c, c1;
tchar wbuf[BUFSIZ];
register tchar *wp = wbuf;
register int i = BUFSIZ - 4;
register bool dolflg;
bool sofar = 0;
#ifdef TRACE
tprintf("TRACE- Dword()\n");
#endif
loop:
c = DgetC(DODOL);
switch (c) {
case DEOF:
deof:
if (sofar == 0)
return (0);
/* finish this word and catch the code above the next time */
unDredc(c);
/* fall into ... */
case '\n':
*wp = 0;
goto ret;
case ' ':
case '\t':
goto loop;
case '`':
/* We preserve ` quotations which are done yet later */
*wp++ = c, --i;
case '\'':
case '"':
/*
* Note that DgetC never returns a QUOTES character
* from an expansion, so only true input quotes will
* get us here or out.
*/
c1 = c;
dolflg = c1 == '"' ? DODOL : 0;
for (;;) {
c = DgetC(dolflg);
if (c == c1)
break;
if (c == '\n' || c == DEOF)
error("Unmatched %c", c1);
if ((c & (QUOTE|TRIM)) == ('\n' | QUOTE))
--wp, ++i;
if (--i <= 0)
goto toochars;
switch (c1) {
case '"':
/*
* Leave any `s alone for later.
* Other chars are all quoted, thus `...`
* can tell it was within "...".
*/
*wp++ = c == '`' ? '`' : c | QUOTE;
break;
case '\'':
/* Prevent all further interpretation */
*wp++ = c | QUOTE;
break;
case '`':
/* Leave all text alone for later */
*wp++ = c;
break;
}
}
if (c1 == '`')
*wp++ = '`', --i;
goto pack; /* continue the word */
case '\\':
c = DgetC(0); /* No $ subst! */
if (c == '\n' || c == DEOF)
goto loop;
c |= QUOTE;
break;
#ifdef MBCHAR /* Could be a space char from aux. codeset. */
default:
if(isauxsp(c))goto loop;
#endif/*MBCHAR*/
}
unDgetC(c);
pack:
sofar = 1;
/* pack up more characters in this word */
for (;;) {
c = DgetC(DODOL);
if (c == '\\') {
c = DgetC(0);
if (c == DEOF)
goto deof;
if (c == '\n')
c = ' ';
else
c |= QUOTE;
}
if (c == DEOF)
goto deof;
if (cmap(c, _SP|_NL|_Q|_Q1)
||isauxsp(c)) { /* sp \t\n'"` or aux. sp*/
unDgetC(c);
if (cmap(c, QUOTES))
goto loop;
*wp++ = 0;
goto ret;
}
if (--i <= 0)
toochars:
error("Word too long");
*wp++ = c;
}
ret:
Gcat(S_ /* "" */, wbuf);
return (1);
}
/*
* Get a character, performing $ substitution unless flag is 0.
* Any QUOTES character which is returned from a $ expansion is
* QUOTEd so that it will not be recognized above.
*/
DgetC(flag)
register int flag;
{
register int c;
top:
if (c = Dpeekc) {
Dpeekc = 0;
return (c);
}
if (lap) {
c = *lap++ & (QUOTE|TRIM);
if (c == 0) {
lap = 0;
goto top;
}
quotspec:
if (cmap(c, QUOTES))
return (c | QUOTE);
return (c);
}
if (dolp) {
if (c = *dolp++ & (QUOTE|TRIM))
goto quotspec;
if (dolcnt > 0) {
setDolp(*dolnxt++);
--dolcnt;
return (' ');
}
dolp = 0;
}
if (dolcnt > 0) {
setDolp(*dolnxt++);
--dolcnt;
goto top;
}
c = Dredc();
if (c == '$' && flag) {
Dgetdol();
goto top;
}
return (c);
}
tchar *nulvec[] = { 0 };
struct varent nulargv = { nulvec, S_argv, 0 };
/*
* Handle the multitudinous $ expansion forms.
* Ugh.
*/
Dgetdol()
{
register tchar *np;
register struct varent *vp;
tchar name[20];
int c, sc;
int subscr = 0, lwb = 1, upb = 0;
bool dimen = 0, bitset = 0;
tchar wbuf[BUFSIZ];
#ifdef TRACE
tprintf("TRACE- Dgetdol()\n");
#endif
dolmod = dolmcnt = 0;
c = sc = DgetC(0);
if (c == '{')
c = DgetC(0); /* sc is { to take } later */
if ((c & TRIM) == '#')
dimen++, c = DgetC(0); /* $# takes dimension */
else if (c == '?')
bitset++, c = DgetC(0); /* $? tests existence */
switch (c) {
case '$':
if (dimen || bitset)
goto syntax; /* No $?$, $#$ */
setDolp(doldol);
goto eatbrac;
case '<'|QUOTE:
if (dimen || bitset)
goto syntax; /* No $?<, $#< */
for (np = wbuf; read_(OLDSTD, np, 1) == 1; np++) {
if (np >= &wbuf[BUFSIZ-1])
error("$< line too long");
if (*np <= 0 || *np == '\n')
break;
}
*np = 0;
/*
* KLUDGE: dolmod is set here because it will
* cause setDolp to call domod and thus to copy wbuf.
* Otherwise setDolp would use it directly. If we saved
* it ourselves, no one would know when to free it.
* The actual function of the 'q' causes filename
* expansion not to be done on the interpolated value.
*/
dolmod = 'q';
dolmcnt = 10000;
setDolp(wbuf);
goto eatbrac;
case DEOF:
case '\n':
goto syntax;
case '*':
(void) strcpy_(name, S_argv);
vp = adrof(S_argv);
subscr = -1; /* Prevent eating [...] */
break;
default:
np = name;
if (digit(c)) {
if (dimen)
goto syntax; /* No $#1, e.g. */
subscr = 0;
do {
subscr = subscr * 10 + c - '0';
c = DgetC(0);
} while (digit(c));
unDredc(c);
if (subscr < 0)
goto oob;
if (subscr == 0) {
if (bitset) {
dolp = file ? S_1/*"1"*/ : S_0/*"0"*/;
goto eatbrac;
}
if (file == 0)
error("No file for $0");
setDolp(file);
goto eatbrac;
}
if (bitset)
goto syntax;
vp = adrof(S_argv);
if (vp == 0) {
vp = &nulargv;
goto eatmod;
}
break;
}
if (!alnum(c))
goto syntax;
for (;;) {
*np++ = c;
c = DgetC(0);
if (!alnum(c))
break;
if (np >= &name[sizeof(name)/sizeof(*name) - 2])
syntax:
error("Variable syntax");
}
*np++ = 0;
unDredc(c);
vp = adrof(name);
}
if (bitset) {
/* getenv() to getenv_(), because 'name''s type is now tchar * */
/* no need to xalloc */
dolp = (vp || getenv_(name)) ? S_1 /*"1"*/ : S_0/*"0"*/;
goto eatbrac;
}
if (vp == 0) {
/* getenv() to getenv_(), because 'name''s type is now tchar * */
/* no need to xalloc */
np = getenv_(name);
if (np) {
addla(np);
goto eatbrac;
}
udvar(name);
/*NOTREACHED*/
}
c = DgetC(0);
upb = blklen(vp->vec);
if (dimen == 0 && subscr == 0 && c == '[') {
np = name;
for (;;) {
c = DgetC(DODOL); /* Allow $ expand within [ ] */
if (c == ']')
break;
if (c == '\n' || c == DEOF)
goto syntax;
if (np >= &name[sizeof(name)/sizeof(*name) - 2])
goto syntax;
*np++ = c;
}
*np = 0, np = name;
if (dolp || dolcnt) /* $ exp must end before ] */
goto syntax;
if (!*np)
goto syntax;
if (digit(*np)) {
register int i = 0;
while (digit(*np))
i = i * 10 + *np++ - '0';
/* if ((i < 0 || i > upb) && !any(*np, "-*")) {*/
if ((i < 0 || i > upb) && (*np!='-') && (*np!='*')) {
oob:
setname(vp->v_name);
error("Subscript out of range");
}
lwb = i;
if (!*np)
upb = lwb, np = S_AST/*"*"*/;
}
if (*np == '*')
np++;
else if (*np != '-')
goto syntax;
else {
register int i = upb;
np++;
if (digit(*np)) {
i = 0;
while (digit(*np))
i = i * 10 + *np++ - '0';
if (i < 0 || i > upb)
goto oob;
}
if (i < lwb)
upb = lwb - 1;
else
upb = i;
}
if (lwb == 0) {
if (upb != 0)
goto oob;
upb = -1;
}
if (*np)
goto syntax;
} else {
if (subscr > 0)
if (subscr > upb)
lwb = 1, upb = 0;
else
lwb = upb = subscr;
unDredc(c);
}
if (dimen) {
tchar *cp = putn(upb - lwb + 1);
addla(cp);
xfree(cp);
} else {
eatmod:
c = DgetC(0);
if (c == ':') {
c = DgetC(0), dolmcnt = 1;
if (c == 'g')
c = DgetC(0), dolmcnt = 10000;
if (!any(c, S_htrqxe))
error("Bad : mod in $");
dolmod = c;
if (c == 'q')
dolmcnt = 10000;
} else
unDredc(c);
dolnxt = &vp->vec[lwb - 1];
dolcnt = upb - lwb + 1;
}
eatbrac:
if (sc == '{') {
c = Dredc();
if (c != '}')
goto syntax;
}
}
setDolp(cp)
register tchar *cp;
{
register tchar *dp;
#ifdef TRACE
tprintf("TRACE- setDolp()\n");
#endif
if (dolmod == 0 || dolmcnt == 0) {
dolp = cp;
return;
}
dp = domod(cp, dolmod);
if (dp) {
dolmcnt--;
addla(dp);
xfree(dp);
} else
addla(cp);
dolp = S_/*""*/;
}
unDredc(c)
int c;
{
Dpeekrd = c;
}
Dredc()
{
register int c;
if (c = Dpeekrd) {
Dpeekrd = 0;
return (c);
}
if (Dcp && (c = *Dcp++))
return (c&(QUOTE|TRIM));
if (*Dvp == 0) {
Dcp = 0;
return (DEOF);
}
Dcp = *Dvp++;
return (' ');
}
Dtestq(c)
register int c;
{
if (cmap(c, QUOTES))
gflag = 1;
}
/*
* Form a shell temporary file (in unit 0) from the words
* of the shell input up to a line the same as "term".
* Unit 0 should have been closed before this call.
*/
heredoc(term)
tchar *term;
{
register int c;
tchar *Dv[2];
tchar obuf[BUFSIZ], lbuf[BUFSIZ], mbuf[BUFSIZ];
int ocnt, lcnt, mcnt;
register tchar *lbp, *obp, *mbp;
tchar **vp;
bool quoted;
#ifdef TRACE
tprintf("TRACE- heredoc()\n");
#endif
if (creat_(shtemp, 0600) < 0)
Perror(shtemp);
(void) close(0);
if (open_(shtemp, 2) < 0) {
int oerrno = errno;
(void) unlink_(shtemp);
errno = oerrno;
Perror(shtemp);
}
(void) unlink_(shtemp); /* 0 0 inode! */
Dv[0] = term; Dv[1] = NOSTR; gflag = 0;
trim(Dv); rscan(Dv, Dtestq); quoted = gflag;
ocnt = BUFSIZ; obp = obuf;
for (;;) {
/*
* Read up a line
*/
lbp = lbuf; lcnt = BUFSIZ - 4;
for (;;) {
c = readc(1); /* 1 -> Want EOF returns */
if (c < 0) {
setname(term);
bferr("<< terminator not found");
}
if (c == '\n')
break;
if (c &= TRIM) {
*lbp++ = c;
if (--lcnt < 0) {
setname(S_LESLES/*"<<"*/);
error("Line overflow");
}
}
}
*lbp = 0;
/*
* Compare to terminator -- before expansion
*/
if (eq(lbuf, term)) {
(void) write_(0, obuf, BUFSIZ - ocnt);
(void) lseek(0, (off_t)0, 0);
return;
}
/*
* If term was quoted or -n just pass it on
*/
if (quoted || noexec) {
*lbp++ = '\n'; *lbp = 0;
for (lbp = lbuf; c = *lbp++;) {
*obp++ = c;
if (--ocnt == 0) {
(void) write_(0, obuf, BUFSIZ);
obp = obuf; ocnt = BUFSIZ;
}
}
continue;
}
/*
* Term wasn't quoted so variable and then command
* expand the input line
*/
Dcp = lbuf; Dvp = Dv + 1; mbp = mbuf; mcnt = BUFSIZ - 4;
for (;;) {
c = DgetC(DODOL);
if (c == DEOF)
break;
if ((c &= TRIM) == 0)
continue;
/* \ quotes \ $ ` here */
if (c =='\\') {
c = DgetC(0);
/* if (!any(c, "$\\`"))*/
if ((c!='$')&&(c!='\\')&&(c!='`'))
unDgetC(c | QUOTE), c = '\\';
else
c |= QUOTE;
}
*mbp++ = c;
if (--mcnt == 0) {
setname(S_LESLES/*"<<"*/);
bferr("Line overflow");
}
}
*mbp++ = 0;
/*
* If any ` in line do command substitution
*/
mbp = mbuf;
if (any('`', mbp)) {
/*
* 1 arg to dobackp causes substitution to be literal.
* Words are broken only at newlines so that all blanks
* and tabs are preserved. Blank lines (null words)
* are not discarded.
*/
vp = dobackp(mbuf, 1);
} else
/* Setup trivial vector similar to return of dobackp */
Dv[0] = mbp, Dv[1] = NOSTR, vp = Dv;
/*
* Resurrect the words from the command substitution
* each separated by a newline. Note that the last
* newline of a command substitution will have been
* discarded, but we put a newline after the last word
* because this represents the newline after the last
* input line!
*/
for (; *vp; vp++) {
for (mbp = *vp; *mbp; mbp++) {
*obp++ = *mbp & TRIM;
if (--ocnt == 0) {
(void) write_(0, obuf, BUFSIZ);
obp = obuf; ocnt = BUFSIZ;
}
}
*obp++ = '\n';
if (--ocnt == 0) {
(void) write_(0, obuf, BUFSIZ);
obp = obuf; ocnt = BUFSIZ;
}
}
if (pargv)
blkfree(pargv), pargv = 0;
}
}

173
bin/csh/sh.err.c Normal file
View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.err.c 1.1 92/07/30 SMI; from UCB 5.3 5/13/86";
#endif
#include "sh.h"
#include <sys/ioctl.h>
#include <stdlib.h>
#include "sh.tconst.h"
/*
* C Shell
*/
bool errspl; /* Argument to error was spliced by seterr2 */
tchar one[2] = { '1', 0 };
tchar *onev[2] = { one, NOSTR };
/*
* Print error string s with optional argument arg.
* This routine always resets or exits. The flag haderr
* is set so the routine who catches the unwind can propogate
* it if they want.
*
* Note that any open files at the point of error will eventually
* be closed in the routine process in sh.c which is the only
* place error unwinds are ever caught.
*/
/*VARARGS1*/
error(s, arg)
char *s;
{
register tchar **v;
register char *ep;
/*
* Must flush before we print as we wish output before the error
* to go on (some form of) standard output, while output after
* goes on (some form of) diagnostic output.
* If didfds then output will go to 1/2 else to FSHOUT/FSHDIAG.
* See flush in sh.print.c.
*/
flush();
haderr = 1; /* Now to diagnostic output */
timflg = 0; /* This isn't otherwise reset */
if (v = pargv)
pargv = 0, blkfree(v);
if (v = gargv)
gargv = 0, blkfree(v);
/*
* A zero arguments causes no printing, else print
* an error diagnostic here.
*/
if (s)
printf(s, arg), printf(".\n");
didfds = 0; /* Forget about 0,1,2 */
if ((ep = err) && errspl) {
errspl = 0;
xfree(ep);
}
errspl = 0;
/*
* Go away if -e or we are a child shell
*/
if (exiterr || child)
exit(1);
/*
* Reset the state of the input.
* This buffered seek to end of file will also
* clear the while/foreach stack.
*/
btoeof();
setq(S_status, onev, &shvhed);
if (tpgrp > 0)
(void) ioctl(FSHTTY, TIOCSPGRP, (char *)&tpgrp);
reset(); /* Unwind */
}
/*
* Perror is the shells version of perror which should otherwise
* never be called.
*/
Perror(s)
tchar *s;
{
char chbuf[BUFSIZ];
/*
* Perror uses unit 2, thus if we didn't set up the fd's
* we must set up unit 2 now else the diagnostic will disappear
*/
if (!didfds) {
register int oerrno = errno;
(void) dcopy(SHDIAG, 2);
errno = oerrno;
}
tstostr(chbuf, s);
perror(chbuf);
error(NULL); /* To exit or unwind */
}
bferr(cp)
char *cp;
{
flush();
haderr = 1;
printf("%t: ", bname);
error(cp);
}
/*
* The parser and scanner set up errors for later by calling seterr,
* which sets the variable err as a side effect; later to be tested,
* e.g. in process.
*/
seterr(s)
char *s;
{
if (err == 0)
err = s, errspl = 0;
}
/* Set err to a splice of cp and dp, to be freed later in error() */
seterr2(cp, dp)
tchar *cp;
char *dp;
{
char chbuf[BUFSIZ];
if (err)
return;
/* Concatinate cp and dp in the allocated space. */
tstostr(chbuf, cp);
err = (char *)xalloc(strlen(chbuf)+strlen(dp)+1);
strcpy(err, chbuf);
strcat(err, dp);
errspl++;/* Remember to xfree(err). */
}
/* Set err to a splice of cp with a string form of character d */
seterrc(cp, d)
char *cp;
tchar d;
{
char chbuf[MB_LEN_MAX+1];
#ifdef MBCHAR
wchar_t wcd=(wchar_t)(d&TRIM);
(void) wctomb(chbuf, wcd); /* chbuf holds d in multibyte representation. */
#else
chbuf[0]=(char)(d&TRIM); chbuf[1]=(char)0;
#endif
/* Concatinate cp and d in the allocated space. */
err = (char *)xalloc(strlen(cp)+strlen(chbuf)+1);
strcpy(err, cp);
strcat(err, chbuf);
errspl++; /* Remember to xfree(err). */
}

439
bin/csh/sh.exec.c Normal file
View File

@@ -0,0 +1,439 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.exec.c 1.1 92/07/30 SMI; from UCB 5.2 6/6/85";
#endif
#include "sh.h"
#include <sys/dir.h>
#include "sh.tconst.h"
/*
* C shell
*/
/*
* System level search and execute of a command.
* We look in each directory for the specified command name.
* If the name contains a '/' then we execute only the full path name.
* If there is no search path then we execute only full path names.
*/
/*
* As we search for the command we note the first non-trivial error
* message for presentation to the user. This allows us often
* to show that a file has the wrong mode/no access when the file
* is not in the last component of the search path, so we must
* go on after first detecting the error.
*/
char *exerr; /* Execution error message */
tchar *expath; /* Path for exerr */
/*
* Xhash is an array of HSHSIZ bits (HSHSIZ / 8 chars), which are used
* to hash execs. If it is allocated (havhash true), then to tell
* whether ``name'' is (possibly) present in the i'th component
* of the variable path, you look at the bit in xhash indexed by
* hash(hashname("name"), i). This is setup automatically
* after .login is executed, and recomputed whenever ``path'' is
* changed.
* The two part hash function is designed to let texec() call the
* more expensive hashname() only once and the simple hash() several
* times (once for each path component checked).
* Byte size is assumed to be 8.
*/
#define HSHSIZ 8192 /* 1k bytes */
#define HSHMASK (HSHSIZ - 1)
#define HSHMUL 243
char xhash[HSHSIZ / 8];
#define hash(a, b) ((a) * HSHMUL + (b) & HSHMASK)
#define bit(h, b) ((h)[(b) >> 3] & 1 << ((b) & 7)) /* bit test */
#define bis(h, b) ((h)[(b) >> 3] |= 1 << ((b) & 7)) /* bit set */
#ifdef VFORK
int hits, misses;
#endif
extern DIR *opendir_();
/* Dummy search path for just absolute search when no path */
tchar *justabs[] = { S_ /* "" */, 0 };
doexec(t)
register struct command *t;
{
tchar *sav;
register tchar *dp, **pv, **av;
register struct varent *v;
bool slash = any('/', t->t_dcom[0]);
int hashval, hashval1, i;
tchar *blk[2];
#ifdef TRACE
tprintf("TRACE- doexec()\n");
#endif
/*
* Glob the command name. If this does anything, then we
* will execute the command only relative to ".". One special
* case: if there is no PATH, then we execute only commands
* which start with '/'.
*/
dp = globone(t->t_dcom[0]);
sav = t->t_dcom[0];
exerr = 0; expath = t->t_dcom[0] = dp;
xfree(sav);
v = adrof(S_path /*"path"*/);
if (v == 0 && expath[0] != '/')
pexerr();
slash |= gflag;
/*
* Glob the argument list, if necessary.
* Otherwise trim off the quote bits.
*/
gflag = 0; av = &t->t_dcom[1];
tglob(av);
if (gflag) {
av = glob(av);
if (av == 0)
error("No match");
}
blk[0] = t->t_dcom[0];
blk[1] = 0;
av = blkspl(blk, av);
#ifdef VFORK
Vav = av;
#endif
trim(av);
xechoit(av); /* Echo command if -x */
/*
* Since all internal file descriptors are set to close on exec,
* we don't need to close them explicitly here. Just reorient
* ourselves for error messages.
*/
SHIN = 0; SHOUT = 1; SHDIAG = 2; OLDSTD = 0;
/*
* We must do this AFTER any possible forking (like `foo`
* in glob) so that this shell can still do subprocesses.
*/
(void) sigsetmask(0);
/*
* If no path, no words in path, or a / in the filename
* then restrict the command search.
*/
if (v == 0 || v->vec[0] == 0 || slash)
pv = justabs;
else
pv = v->vec;
sav = strspl(S_SLASH /* "/" */, *av); /* / command name for postpending */
#ifdef VFORK
Vsav = sav;
#endif
if (havhash)
hashval = hashname(*av);
i = 0;
#ifdef VFORK
hits++;
#endif
do {
if (!slash && pv[0][0] == '/' && havhash) {
hashval1 = hash(hashval, i);
if (!bit(xhash, hashval1))
goto cont;
}
if (pv[0][0] == 0 || eq(pv[0], S_DOT/*"."*/)) /* don't make ./xxx */
texec(t, *av, av);
else {
dp = strspl(*pv, sav);
#ifdef VFORK
Vdp = dp;
#endif
texec(t, dp, av);
#ifdef VFORK
Vdp = 0;
#endif
xfree(dp);
}
#ifdef VFORK
misses++;
#endif
cont:
pv++;
i++;
} while (*pv);
#ifdef VFORK
hits--;
#endif
#ifdef VFORK
Vsav = 0;
Vav = 0;
#endif
xfree(sav);
xfree( (char *)av);
pexerr();
}
pexerr()
{
#ifdef TRACE
tprintf("TRACE- pexerr()\n");
#endif
/* Couldn't find the damn thing */
setname(expath);
/* xfree(expath); */
if (exerr)
bferr(exerr);
bferr("Command not found");
}
/*
* Execute command f, arg list t.
* Record error message if not found.
* Also do shell scripts here.
*/
texec(cmd, f, t)
register struct command *cmd;
tchar *f;
register tchar **t;
{
register struct varent *v;
register tchar **vp;
extern char *sys_errlist[];
tchar *lastsh[2];
#ifdef TRACE
tprintf("TRACE- texec()\n");
#endif
/* convert cfname and cargs from tchar to char */
tconvert(cmd, f, t);
execv(cmd->cfname, cmd->cargs);
/*
* exec retuned, free up allocations from above
* tconvert(), zero cfname and cargs to prevent
* duplicate free() in freesyn()
*/
xfree(cmd->cfname);
chr_blkfree(cmd->cargs);
cmd->cfname = (char *) 0;
cmd->cargs = (char **) 0;
switch (errno) {
case ENOEXEC:
/* check that this is not a binary file */
{
register int ff = open_(f, 0);
tchar ch;
if (ff != -1 && read_(ff, &ch, 1) == 1 && !isprint(ch)
&& !isspace(ch)) {
printf("Cannot execute binary file.\n");
Perror(f);
(void) close(ff);
return;
}
(void) close(ff);
}
/*
* If there is an alias for shell, then
* put the words of the alias in front of the
* argument list replacing the command name.
* Note no interpretation of the words at this point.
*/
v = adrof1(S_shell /*"shell"*/, &aliases);
if (v == 0) {
#ifdef OTHERSH
register int ff = open_(f, 0);
tchar ch;
#endif
vp = lastsh;
vp[0] = adrof(S_shell /*"shell"*/) ? value(S_shell /*"shell"*/) : S_SHELLPATH/*SHELLPATH*/;
vp[1] = (tchar *) NULL;
#ifdef OTHERSH
if (ff != -1 && read_(ff, &ch, 1) == 1 && ch != '#')
vp[0] = S_OTHERSH/*OTHERSH*/;
(void) close(ff);
#endif
} else
vp = v->vec;
t[0] = f;
t = blkspl(vp, t); /* Splice up the new arglst */
f = *t;
tconvert(cmd, f, t); /* convert tchar to char */
/*
* now done with tchar arg list t,
* free the space calloc'd by above blkspl()
*/
xfree((char *) t);
execv(cmd->cfname, cmd->cargs); /* exec the command */
/* exec returned, same free'ing as above */
xfree(cmd->cfname);
chr_blkfree(cmd->cargs);
cmd->cfname = (char *) 0;
cmd->cargs = (char **) 0;
/* The sky is falling, the sky is falling! */
case ENOMEM:
Perror(f);
case ENOENT:
break;
default:
if (exerr == 0) {
exerr = sys_errlist[errno];
expath = savestr(f);
}
}
}
static
tconvert(cmd, fname, list)
register struct command *cmd;
register tchar *fname, **list;
{
register char **rc;
register int len;
cmd->cfname = tstostr(NULL, fname);
len = blklen(list);
rc = cmd->cargs = (char **)
calloc((u_int) (len + 1), sizeof(char **));
while (len--)
*rc++ = tstostr(NULL, *list++);
*rc = NULL;
}
/*ARGSUSED*/
execash(t, kp)
tchar **t;
register struct command *kp;
{
#ifdef TRACE
tprintf("TRACE- execash()\n");
#endif
rechist();
(void) signal(SIGINT, parintr);
(void) signal(SIGQUIT, parintr);
(void) signal(SIGTERM, parterm); /* if doexec loses, screw */
lshift(kp->t_dcom, 1);
exiterr++;
doexec(kp);
/*NOTREACHED*/
}
xechoit(t)
tchar **t;
{
#ifdef TRACE
tprintf("TRACE- xechoit()\n");
#endif
if (adrof(S_echo /*"echo"*/)) {
flush();
haderr = 1;
blkpr(t), putchar('\n');
haderr = 0;
}
}
dohash()
{
struct stat stb;
DIR *dirp;
register struct direct *dp;
register int cnt;
int i = 0;
struct varent *v = adrof(S_path /*"path"*/);
tchar **pv;
int hashval;
tchar curdir_[MAXNAMLEN+1];
#ifdef TRACE
tprintf("TRACE- dohash()\n");
#endif
havhash = 1;
for (cnt = 0; cnt < sizeof(xhash)/sizeof(*xhash); cnt++)
xhash[cnt] = 0;
if (v == 0)
return;
for (pv = v->vec; *pv; pv++, i++) {
if (pv[0][0] != '/')
continue;
dirp = opendir_(*pv);
if (dirp == NULL)
continue;
if (fstat(dirp->dd_fd, &stb) < 0 || !isdir(stb)) {
closedir(dirp);
continue;
}
while ((dp = readdir(dirp)) != NULL) {
if (dp->d_ino == 0)
continue;
if (dp->d_name[0] == '.' &&
(dp->d_name[1] == '\0' ||
dp->d_name[1] == '.' && dp->d_name[2] == '\0'))
continue;
hashval = hash(hashname(strtots(curdir_,dp->d_name)), i);
bis(xhash, hashval);
}
closedir(dirp);
}
}
dounhash()
{
#ifdef TRACE
tprintf("TRACE- dounhash()\n");
#endif
havhash = 0;
}
#ifdef VFORK
hashstat()
{
#ifdef TRACE
tprintf("TRACE- hashstat_()\n");
#endif
if (hits+misses)
printf("%d hits, %d misses, %d%%\n",
hits, misses, 100 * hits / (hits + misses));
}
#endif
/*
* Hash a command name.
*/
hashname(cp)
register tchar *cp;
{
register long h = 0;
#ifdef TRACE
tprintf("TRACE- hashname()\n");
#endif
while (*cp)
h = hash(h, *cp++);
return ((int) h);
}

655
bin/csh/sh.exp.c Normal file
View File

@@ -0,0 +1,655 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.exp.c 1.1 92/07/30 SMI; from UCB 5.3 6/23/85";
#endif
#include "sh.h"
#include "sh.tconst.h"
/*
* C shell
*/
#define IGNORE 1 /* in ignore, it means to ignore value, just parse */
#define NOGLOB 2 /* in ignore, it means not to globone */
#define ADDOP 1
#define MULOP 2
#define EQOP 4
#define RELOP 8
#define RESTOP 16
#define ANYOP 31
#define EQEQ 1
#define GTR 2
#define LSS 4
#define NOTEQ 6
#define EQMATCH 7
#define NOTEQMATCH 8
exp(vp)
register tchar ***vp;
{
#ifdef TRACE
tprintf("TRACE- exp()\n");
#endif
return (exp0(vp, 0));
}
exp0(vp, ignore)
register tchar ***vp;
bool ignore;
{
register int p1 = exp1(vp, ignore);
#ifdef TRACE
tprintf("TRACE- exp0()\n");
#endif
#ifdef EDEBUG
etraci("exp0 p1", p1, vp);
#endif
if (**vp && eq(**vp, S_BARBAR /*"||"*/)) {
register int p2;
(*vp)++;
p2 = exp0(vp, (ignore&IGNORE) || p1);
#ifdef EDEBUG
etraci("exp0 p2", p2, vp);
#endif
return (p1 || p2);
}
return (p1);
}
exp1(vp, ignore)
register tchar ***vp;
{
register int p1 = exp2(vp, ignore);
#ifdef TRACE
tprintf("TRACE- exp1()\n");
#endif
#ifdef EDEBUG
etraci("exp1 p1", p1, vp);
#endif
if (**vp && eq(**vp, S_ANDAND /*"&&" */)) {
register int p2;
(*vp)++;
p2 = exp1(vp, (ignore&IGNORE) || !p1);
#ifdef EDEBUG
etraci("exp1 p2", p2, vp);
#endif
return (p1 && p2);
}
return (p1);
}
exp2(vp, ignore)
register tchar ***vp;
bool ignore;
{
register int p1 = exp2a(vp, ignore);
#ifdef TRACE
tprintf("TRACE- exp2()\n");
#endif
#ifdef EDEBUG
etraci("exp3 p1", p1, vp);
#endif
if (**vp && eq(**vp, S_BAR /*"|" */)) {
register int p2;
(*vp)++;
p2 = exp2(vp, ignore);
#ifdef EDEBUG
etraci("exp3 p2", p2, vp);
#endif
return (p1 | p2);
}
return (p1);
}
exp2a(vp, ignore)
register tchar ***vp;
bool ignore;
{
register int p1 = exp2b(vp, ignore);
#ifdef TRACE
tprintf("TRACE- exp2a()\n");
#endif
#ifdef EDEBUG
etraci("exp2a p1", p1, vp);
#endif
if (**vp && eq(**vp, S_HAT /*"^" */)) {
register int p2;
(*vp)++;
p2 = exp2a(vp, ignore);
#ifdef EDEBUG
etraci("exp2a p2", p2, vp);
#endif
return (p1 ^ p2);
}
return (p1);
}
exp2b(vp, ignore)
register tchar ***vp;
bool ignore;
{
register int p1 = exp2c(vp, ignore);
#ifdef TRACE
tprintf("TRACE- exp2b()\n");
#endif
#ifdef EDEBUG
etraci("exp2b p1", p1, vp);
#endif
if (**vp && eq(**vp, S_AND /*"&"*/)) {
register int p2;
(*vp)++;
p2 = exp2b(vp, ignore);
#ifdef EDEBUG
etraci("exp2b p2", p2, vp);
#endif
return (p1 & p2);
}
return (p1);
}
exp2c(vp, ignore)
register tchar ***vp;
bool ignore;
{
register tchar *p1 = exp3(vp, ignore);
register tchar *p2;
register int i;
#ifdef TRACE
tprintf("TRACE- exp2c()\n");
#endif
#ifdef EDEBUG
etracc("exp2c p1", p1, vp);
#endif
if (i = isa(**vp, EQOP)) {
(*vp)++;
if (i == EQMATCH || i == NOTEQMATCH)
ignore |= NOGLOB;
p2 = exp3(vp, ignore);
#ifdef EDEBUG
etracc("exp2c p2", p2, vp);
#endif
if (!(ignore&IGNORE)) switch (i) {
case EQEQ:
i = eq(p1, p2);
break;
case NOTEQ:
i = !eq(p1, p2);
break;
case EQMATCH:
i = Gmatch(p1, p2);
break;
case NOTEQMATCH:
i = !Gmatch(p1, p2);
break;
}
xfree(p1), xfree(p2);
return (i);
}
i = egetn(p1);
xfree(p1);
return (i);
}
tchar *
exp3(vp, ignore)
register tchar ***vp;
bool ignore;
{
register tchar *p1, *p2;
register int i;
#ifdef TRACE
tprintf("TRACE- exp3()\n");
#endif
p1 = exp3a(vp, ignore);
#ifdef EDEBUG
etracc("exp3 p1", p1, vp);
#endif
if (i = isa(**vp, RELOP)) {
(*vp)++;
if (**vp && eq(**vp, S_EQ /*"=" */))
i |= 1, (*vp)++;
p2 = exp3(vp, ignore);
#ifdef EDEBUG
etracc("exp3 p2", p2, vp);
#endif
if (!(ignore&IGNORE)) switch (i) {
case GTR:
i = egetn(p1) > egetn(p2);
break;
case GTR|1:
i = egetn(p1) >= egetn(p2);
break;
case LSS:
i = egetn(p1) < egetn(p2);
break;
case LSS|1:
i = egetn(p1) <= egetn(p2);
break;
}
xfree(p1), xfree(p2);
return (putn(i));
}
return (p1);
}
tchar *
exp3a(vp, ignore)
register tchar ***vp;
bool ignore;
{
register tchar *p1, *p2, *op;
register int i;
#ifdef TRACE
tprintf("TRACE- exp3a()\n");
#endif
p1 = exp4(vp, ignore);
#ifdef EDEBUG
etracc("exp3a p1", p1, vp);
#endif
op = **vp;
/* if (op && any(op[0], "<>") && op[0] == op[1]) { */
if (op && (op[0] == '<' || op[0] == '>') && op[0] == op[1]) {
(*vp)++;
p2 = exp3a(vp, ignore);
#ifdef EDEBUG
etracc("exp3a p2", p2, vp);
#endif
if (op[0] == '<')
i = egetn(p1) << egetn(p2);
else
i = egetn(p1) >> egetn(p2);
xfree(p1), xfree(p2);
return (putn(i));
}
return (p1);
}
tchar *
exp4(vp, ignore)
register tchar ***vp;
bool ignore;
{
register tchar *p1, *p2;
register int i = 0;
#ifdef TRACE
tprintf("TRACE- exp4()\n");
#endif
p1 = exp5(vp, ignore);
#ifdef EDEBUG
etracc("exp4 p1", p1, vp);
#endif
if (isa(**vp, ADDOP)) {
register tchar *op = *(*vp)++;
p2 = exp4(vp, ignore);
#ifdef EDEBUG
etracc("exp4 p2", p2, vp);
#endif
if (!(ignore&IGNORE)) switch (op[0]) {
case '+':
i = egetn(p1) + egetn(p2);
break;
case '-':
i = egetn(p1) - egetn(p2);
break;
}
xfree(p1), xfree(p2);
return (putn(i));
}
return (p1);
}
tchar *
exp5(vp, ignore)
register tchar ***vp;
bool ignore;
{
register tchar *p1, *p2;
register int i = 0;
#ifdef TRACE
tprintf("TRACE- exp5()\n");
#endif
p1 = exp6(vp, ignore);
#ifdef EDEBUG
etracc("exp5 p1", p1, vp);
#endif
if (isa(**vp, MULOP)) {
register tchar *op = *(*vp)++;
p2 = exp5(vp, ignore);
#ifdef EDEBUG
etracc("exp5 p2", p2, vp);
#endif
if (!(ignore&IGNORE)) switch (op[0]) {
case '*':
i = egetn(p1) * egetn(p2);
break;
case '/':
i = egetn(p2);
if (i == 0)
error("Divide by 0");
i = egetn(p1) / i;
break;
case '%':
i = egetn(p2);
if (i == 0)
error("Mod by 0");
i = egetn(p1) % i;
break;
}
xfree(p1), xfree(p2);
return (putn(i));
}
return (p1);
}
tchar *
exp6(vp, ignore)
register tchar ***vp;
{
int ccode, i;
register tchar *cp, *dp, *ep;
#ifdef TRACE
tprintf("TRACE- exp6()\n");
#endif
if (**vp == 0)
bferr("Expression syntax");
if (eq(**vp, S_EXAS /* "!" */)) {
(*vp)++;
cp = exp6(vp, ignore);
#ifdef EDEBUG
etracc("exp6 ! cp", cp, vp);
#endif
i = egetn(cp);
xfree(cp);
return (putn(!i));
}
if (eq(**vp, S_TIL /*"~" */)) {
(*vp)++;
cp = exp6(vp, ignore);
#ifdef EDEBUG
etracc("exp6 ~ cp", cp, vp);
#endif
i = egetn(cp);
xfree(cp);
return (putn(~i));
}
if (eq(**vp, S_LPAR /*"(" */)) {
(*vp)++;
ccode = exp0(vp, ignore);
#ifdef EDEBUG
etraci("exp6 () ccode", ccode, vp);
#endif
if (*vp == 0 || **vp == 0 || ***vp != ')')
bferr("Expression syntax");
(*vp)++;
return (putn(ccode));
}
if (eq(**vp, S_LBRA /* "{" */)) {
register tchar **v;
struct command faket;
tchar *fakecom[2];
faket.t_dtyp = TCOM;
faket.t_dflg = 0;
faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0;
faket.t_dcom = fakecom;
fakecom[0] = S_BRAPPPBRA /*"{ ... }" */;
fakecom[1] = NOSTR;
(*vp)++;
v = *vp;
for (;;) {
if (!**vp)
bferr("Missing }");
if (eq(*(*vp)++, S_RBRA /*"}" */))
break;
}
if (ignore&IGNORE)
return (S_ /*""*/);
psavejob();
if (pfork(&faket, -1) == 0) {
*--(*vp) = 0;
evalav(v);
exitstat();
}
pwait();
prestjob();
#ifdef EDEBUG
etraci("exp6 {} status", egetn(value("status")), vp);
#endif
return (putn(egetn(value(S_status /*"status" */)) == 0));
}
if (isa(**vp, ANYOP))
return (S_ /*""*/);
cp = *(*vp)++;
if (*cp == '-' && any(cp[1], S_erwxfdzo /*"erwxfdzo" */)) {
struct stat stb;
if (cp[2] != '\0')
bferr("Malformed file inquiry");
/*
* Detect missing file names by checking for operator
* in the file name position. However, if an operator
* name appears there, we must make sure that there's
* no file by that name (e.g., "/") before announcing
* an error. Even this check isn't quite right, since
* it doesn't take globbing into account.
*/
if (isa(**vp, ANYOP) && stat_(**vp, &stb))
bferr("Missing file name");
dp = *(*vp)++;
if (ignore&IGNORE)
return (S_ /*""*/);
ep = globone(dp);
switch (cp[1]) {
case 'r':
i = !access_(ep, 4);
break;
case 'w':
i = !access_(ep, 2);
break;
case 'x':
i = !access_(ep, 1);
break;
default:
if (stat_(ep, &stb)) {
xfree(ep);
return (S_0 /*"0"*/);
}
switch (cp[1]) {
case 'f':
i = (stb.st_mode & S_IFMT) == S_IFREG;
break;
case 'd':
i = (stb.st_mode & S_IFMT) == S_IFDIR;
break;
case 'z':
i = stb.st_size == 0;
break;
case 'e':
i = 1;
break;
case 'o':
i = stb.st_uid == uid;
break;
}
}
#ifdef EDEBUG
etraci("exp6 -? i", i, vp);
#endif
xfree(ep);
return (putn(i));
}
#ifdef EDEBUG
etracc("exp6 default", cp, vp);
#endif
return (ignore&NOGLOB ? savestr(cp) : globone(cp));
}
evalav(v)
register tchar **v;
{
struct wordent paraml;
register struct wordent *hp = &paraml;
struct command *t;
register struct wordent *wdp = hp;
#ifdef TRACE
tprintf("TRACE- evalav()\n");
#endif
set(S_status /*"status" */, S_0 /*"0"*/);
hp->prev = hp->next = hp;
hp->word = S_ /*""*/;
while (*v) {
register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
new->prev = wdp;
new->next = hp;
wdp->next = new;
wdp = new;
wdp->word = savestr(*v++);
}
hp->prev = wdp;
alias(&paraml);
t = syntax(paraml.next, &paraml, 0);
if (err)
error(err);
execute(t, -1);
freelex(&paraml), freesyn(t);
}
isa(cp, what)
register tchar *cp;
register int what;
{
#ifdef TRACE
tprintf("TRACE- isa()\n");
#endif
if (cp == 0)
return ((what & RESTOP) != 0);
if (cp[1] == 0) {
if (what & ADDOP && (*cp == '+' || *cp == '-'))
return (1);
if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
return (1);
if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
*cp == '~' || *cp == '^' || *cp == '"'))
return (1);
} else if (cp[2] == 0) {
if (what & RESTOP) {
if (cp[0] == '|' && cp[1] == '&')
return (1);
if (cp[0] == '<' && cp[1] == '<')
return (1);
if (cp[0] == '>' && cp[1] == '>')
return (1);
}
if (what & EQOP) {
if (cp[0] == '=') {
if (cp[1] == '=')
return (EQEQ);
if (cp[1] == '~')
return (EQMATCH);
} else if (cp[0] == '!') {
if (cp[1] == '=')
return (NOTEQ);
if (cp[1] == '~')
return (NOTEQMATCH);
}
}
}
if (what & RELOP) {
if (*cp == '<')
return (LSS);
if (*cp == '>')
return (GTR);
}
return (0);
}
egetn(cp)
register tchar *cp;
{
#ifdef TRACE
tprintf("TRACE- egetn()\n");
#endif
if (*cp && *cp != '-' && !digit(*cp))
bferr("Expression syntax");
return (getn(cp));
}
/* Phew! */
#ifdef EDEBUG
etraci(str, i, vp)
tchar *str;
int i;
tchar ***vp;
{
printf("%s=%d\t", str, i);
blkpr(*vp);
printf("\n");
}
etracc(str, cp, vp)
tchar *str, *cp;
tchar ***vp;
{
printf("%s=%s\t", str, cp);
blkpr(*vp);
printf("\n");
}
#endif

780
bin/csh/sh.file.c Normal file
View File

@@ -0,0 +1,780 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.file.c 1.1 92/07/30 SMI; from UCB 5.3 2/12/86";
#endif
#ifdef FILEC
/*
* Tenex style file name recognition, .. and more.
* History:
* Author: Ken Greer, Sept. 1975, CMU.
* Finally got around to adding to the Cshell., Ken Greer, Dec. 1981.
*/
#include "sh.h"
#include <sys/dir.h>
#include <pwd.h>
#include <sys/filio.h>
#include <sys/termios.h>
#include "sh.tconst.h"
#define TRUE 1
#define FALSE 0
#define ON 1
#define OFF 0
#define ESC '\033'
extern putchar();
extern DIR *opendir_();
static char *BELL = "\07";
static char *CTRLR = "^R\n";
typedef enum {LIST, RECOGNIZE} COMMAND;
static jmp_buf osetexit; /* saved setexit() state */
static struct termios tty_save; /* saved terminal state */
static struct termios tty_new; /* new terminal state */
/*
* Put this here so the binary can be patched with adb to enable file
* completion by default. Filec controls completion, nobeep controls
* ringing the terminal bell on incomplete expansions.
*/
bool filec = 0;
static
setup_tty(on)
int on;
{
int omask;
#ifdef TRACE
tprintf("TRACE- setup_tty()\n");
#endif
omask = sigblock(sigmask(SIGINT));
if (on) {
/*
* The shell makes sure that the tty is not in some weird state
* and fixes it if it is. But it should be noted that the
* tenex routine will not work correctly in CBREAK or RAW mode
* so this code below is, therefore, mandatory.
*
* Also, in order to recognize the ESC (filename-completion)
* character, set EOL to ESC. This way, ESC will terminate
* the line, but still be in the input stream.
* EOT (filename list) will also terminate the line,
* but will not appear in the input stream.
*
* The getexit/setexit contortions ensure that the
* tty state will be restored if the user types ^C.
*/
(void) ioctl(SHIN, TCGETS, (char *)&tty_save);
getexit(osetexit);
if (setjmp(reslab)) {
(void) ioctl(SHIN, TCSETSW, (char *)&tty_save);
resexit(osetexit);
reset();
}
tty_new = tty_save;
tty_new.c_cc[VEOL] = ESC;
tty_new.c_iflag |= IMAXBEL | BRKINT | IGNPAR;
tty_new.c_lflag |= ICANON;
tty_new.c_oflag &= ~OCRNL;
(void) ioctl(SHIN, TCSETSW, (char *)&tty_new);
} else {
/*
* Reset terminal state to what user had when invoked
*/
(void) ioctl(SHIN, TCSETSW, (char *)&tty_save);
resexit(osetexit);
}
(void) sigsetmask(omask);
}
static
termchars()
{
extern char *tgetstr();
char bp[1024];
static char area[256];
static int been_here = 0;
char *ap = area;
register char *s;
char *term;
#ifdef TRACE
tprintf("TRACE- termchars()\n");
#endif
if (been_here)
return;
been_here = TRUE;
if ((term = getenv("TERM")) == NULL)
return;
if (tgetent(bp, term) != 1)
return;
if (s = tgetstr("vb", &ap)) /* Visible Bell */
BELL = s;
}
/*
* Move back to beginning of current line
*/
static
back_to_col_1()
{
int omask;
#ifdef TRACE
tprintf("TRACE- back_to_col_1()\n");
#endif
omask = sigblock(sigmask(SIGINT));
(void) write(SHOUT, "\r", 1);
(void) sigsetmask(omask);
}
/*
* Push string contents back into tty queue
*/
static
pushback(string, echoflag)
tchar *string;
int echoflag;
{
register tchar *p;
struct termios tty;
int omask;
#ifdef TRACE
tprintf("TRACE- puchback()\n");
#endif
omask = sigblock(sigmask(SIGINT));
tty = tty_new;
if (!echoflag)
tty.c_lflag &= ~ECHO;
(void) ioctl(SHIN, TCSETSF, (char *)&tty);
for (p = string; *p; p++){
char mbc[MB_LEN_MAX];
int i, j=wctomb(mbc, (wchar_t)*p);
if(j<0) continue; /* Error! But else what can we do? */
for(i=0;i<j;++i)
(void) ioctl(SHIN, TIOCSTI, mbc+i);
}
if (tty.c_lflag != tty_new.c_lflag)
(void) ioctl(SHIN, TCSETS, (char *)&tty_new);
(void) sigsetmask(omask);
}
/*
* Concatenate src onto tail of des.
* Des is a string whose maximum length is count.
* Always null terminate.
*/
catn(des, src, count)
register tchar *des, *src;
register count;
{
#ifdef TRACE
tprintf("TRACE- catn()\n");
#endif
while (--count >= 0 && *des)
des++;
while (--count >= 0)
if ((*des++ = *src++) == '\0')
return;
*des = '\0';
}
static
max(a, b)
{
return (a > b ? a : b);
}
/*
* Like strncpy but always leave room for trailing \0
* and always null terminate.
*/
copyn(des, src, count)
register tchar *des, *src;
register count;
{
#ifdef TRACE
tprintf("TRACE- copyn()\n");
#endif
while (--count >= 0)
if ((*des++ = *src++) == '\0')
return;
*des = '\0';
}
/*
* For qsort()
*/
static
fcompare(file1, file2)
tchar **file1, **file2;
{
#ifdef TRACE
tprintf("TRACE- fcompare()\n");
#endif
return (strcmp_(*file1, *file2));
}
static char
filetype(dir, file, nosym)
tchar *dir, *file;
int nosym;
{
tchar path[MAXPATHLEN + 1];
struct stat statb;
#ifdef TRACE
tprintf("TRACE- filetype()\n");
#endif
if (dir) {
catn(strcpy_(path, dir), file, MAXPATHLEN);
if (nosym) {
if (stat_(path, &statb) < 0)
return (' ');
} else {
if (lstat_(path, &statb) < 0)
return (' ');
}
if ((statb.st_mode & S_IFMT) == S_IFLNK)
return ('@');
if ((statb.st_mode & S_IFMT) == S_IFDIR)
return ('/');
if (((statb.st_mode & S_IFMT) == S_IFREG) &&
(statb.st_mode & 011))
return ('*');
}
return (' ');
}
/*
* Print sorted down columns
*/
static
print_by_column(dir, items, count, looking_for_command)
tchar *dir, *items[];
int looking_for_command;
{
register int i, rows, r, c, maxwidth = 0, columns;
#ifdef TRACE
tprintf("TRACE- print_by_column()\n");
#endif
for (i = 0; i < count; i++)
maxwidth = max(maxwidth, tswidth(items[i]));
/* for the file tag and space */
maxwidth += looking_for_command ? 1 : 2;
columns = 78 / maxwidth;
rows = (count + (columns - 1)) / columns;
for (r = 0; r < rows; r++) {
for (c = 0; c < columns; c++) {
i = c * rows + r;
if (i < count) {
register int w;
printf("%t", items[i]);
w = tswidth(items[i]);
/*
* Print filename followed by
* '@' or '/' or '*' or ' '
*/
if (!looking_for_command) {
putchar(filetype(dir, items[i], 0));
w++;
}
if (c < columns - 1) /* last column? */
for (; w < maxwidth; w++)
putchar(' ');
}
}
putchar('\n');
}
}
/*
* Expand file name with possible tilde usage
* ~person/mumble
* expands to
* home_directory_of_person/mumble
*/
tchar *
tilde(new, old)
tchar *new, *old;
{
register tchar *o, *p;
register struct passwd *pw;
static tchar person[40];
char person_[40]; /* work */
tchar *pw_dir; /* work */
#ifdef TRACE
tprintf("TRACE- tilde()\n");
#endif
if (old[0] != '~')
return (strcpy_(new, old));
for (p = person, o = &old[1]; *o && *o != '/'; *p++ = *o++)
;
*p = '\0';
if (person[0] == '\0')
(void) strcpy_(new, value(S_home /*"home"*/));
else {
pw = getpwnam(tstostr(person_,person));
if (pw == NULL)
return (NULL);
pw_dir = strtots((tchar *)NULL, pw->pw_dir); /* allocate */
(void) strcpy_(new, pw_dir);
xfree(pw_dir); /* free it */
}
(void) strcat_(new, o);
return (new);
}
/*
* Cause pending line to be printed
*/
static
sim_retype()
{
#ifdef notdef
struct termios tty_pending;
#ifdef TRACE
tprintf("TRACE- sim_retypr()\n");
#endif
tty_pending = tty_new;
tty_pending.c_lflag |= PENDIN;
(void) ioctl(SHIN, TCSETS, (char *)&tty_pending);
#else
#ifdef TRACE
tprintf("TRACE- sim_retype()\n");
#endif
(void) write(SHOUT, CTRLR, strlen(CTRLR));
printprompt();
#endif
}
static
beep()
{
#ifdef TRACE
tprintf("TRACE- beep()\n");
#endif
if (adrof(S_nobeep /*"nobeep" */) == 0)
(void) write(SHOUT, BELL, strlen(BELL));
}
/*
* Erase that silly ^[ and
* print the recognized part of the string
*/
static
print_recognized_stuff(recognized_part)
tchar *recognized_part;
{
int unit;
unit = didfds ? 1 : SHOUT;
#ifdef TRACE
tprintf("TRACE- print_recognized_stuff()\n");
#endif
/* An optimized erasing of that silly ^[ */
flush();
switch (tswidth(recognized_part)) {
case 0: /* erase two characters: ^[ */
write(unit, "\010\010 \010\010", strlen("\010\010 \010\010"));
break;
case 1: /* overstrike the ^, erase the [ */
write(unit, "\010\010", 2);
printf("%t", recognized_part);
write(unit, " \010\010", 4);
break;
default: /* overstrike both characters ^[ */
write(unit, "\010\010", 2);
printf("%t", recognized_part);
break;
}
flush();
}
/*
* Parse full path in file into 2 parts: directory and file names
* Should leave final slash (/) at end of dir.
*/
static
extract_dir_and_name(path, dir, name)
tchar *path, *dir, *name;
{
register tchar *p;
#ifdef TRACE
tprintf("TRACE- extract_dir_and_name()\n");
#endif
p = rindex_(path, '/');
if (p == NOSTR) {
copyn(name, path, MAXNAMLEN);
dir[0] = '\0';
} else {
copyn(name, ++p, MAXNAMLEN);
copyn(dir, path, p - path);
}
}
tchar *
getentry(dir_fd, looking_for_lognames)
DIR *dir_fd;
{
register struct passwd *pw;
register struct direct *dirp;
/*
* For char * -> tchar * Conversion
*/
static tchar strbuf[MAXNAMLEN+1];
#ifdef TRACE
tprintf("TRACE- getentry()\n");
#endif
if (looking_for_lognames) {
if ((pw = getpwent ()) == NULL)
return (NULL);
return (strtots(strbuf,pw->pw_name));
}
if (dirp = readdir(dir_fd))
return (strtots(strbuf,dirp->d_name));
return (NULL);
}
static
free_items(items)
register tchar **items;
{
register int i;
#ifdef TRACE
tprintf("TRACE- free_items()\n");
#endif
for (i = 0; items[i]; i++)
free(items[i]);
free( (char *)items);
}
#define FREE_ITEMS(items) { \
int omask;\
\
omask = sigblock(sigmask(SIGINT));\
free_items(items);\
items = NULL;\
(void) sigsetmask(omask);\
}
/*
* Perform a RECOGNIZE or LIST command on string "word".
*/
static
search2(word, command, max_word_length)
tchar *word;
COMMAND command;
{
static tchar **items = NULL;
register DIR *dir_fd;
register numitems = 0, ignoring = TRUE, nignored = 0;
register name_length, looking_for_lognames;
tchar tilded_dir[MAXPATHLEN + 1], dir[MAXPATHLEN + 1];
tchar name[MAXNAMLEN + 1], extended_name[MAXNAMLEN+1];
tchar *entry;
#define MAXITEMS 1024
#ifdef TRACE
tprintf("TRACE- search2()\n");
#endif
if (items != NULL)
FREE_ITEMS(items);
looking_for_lognames = (*word == '~') && (index_(word, '/') == NULL);
if (looking_for_lognames) {
(void) setpwent();
copyn(name, &word[1], MAXNAMLEN); /* name sans ~ */
} else {
extract_dir_and_name(word, dir, name);
if (tilde(tilded_dir, dir) == 0)
return (0);
dir_fd = opendir_(*tilded_dir ? tilded_dir : S_DOT /*"."*/);
if (dir_fd == NULL)
return (0);
}
again: /* search for matches */
name_length = strlen_(name);
for (numitems = 0; entry = getentry(dir_fd, looking_for_lognames); ) {
if (!is_prefix(name, entry))
continue;
/* Don't match . files on null prefix match */
if (name_length == 0 && entry[0] == '.' &&
!looking_for_lognames)
continue;
if (command == LIST) {
if (numitems >= MAXITEMS) {
printf ("\nYikes!! Too many %s!!\n",
looking_for_lognames ?
"names in password file":"files");
break;
}
if (items == NULL)
items = (tchar **) calloc(sizeof (items[1]),
MAXITEMS);
items[numitems] = (tchar *)xalloc((unsigned)(strlen_(entry) + 1)*sizeof(tchar));
copyn(items[numitems], entry, MAXNAMLEN);
numitems++;
} else { /* RECOGNIZE command */
if (ignoring && ignored(entry))
nignored++;
else if (recognize(extended_name,
entry, name_length, ++numitems))
break;
}
}
if (ignoring && numitems == 0 && nignored > 0) {
ignoring = FALSE;
nignored = 0;
if (looking_for_lognames)
(void)setpwent();
else
rewinddir(dir_fd);
goto again;
}
if (looking_for_lognames)
(void) endpwent();
else
closedir(dir_fd);
if (command == RECOGNIZE && numitems > 0) {
if (looking_for_lognames)
copyn(word, S_TIL /*"~" */, 1);
else
/* put back dir part */
copyn(word, dir, max_word_length);
/* add extended name */
catn(word, extended_name, max_word_length);
return (numitems);
}
if (command == LIST) {
qsort( (tchar *)items, numitems, sizeof(items[1]), fcompare);
/*
* Never looking for commands in this version, so final
* argument forced to 0. If command name completion is
* reinstated, this must change.
*/
print_by_column(looking_for_lognames ? NULL : tilded_dir,
items, numitems, 0);
if (items != NULL)
FREE_ITEMS(items);
}
return (0);
}
/*
* Object: extend what user typed up to an ambiguity.
* Algorithm:
* On first match, copy full entry (assume it'll be the only match)
* On subsequent matches, shorten extended_name to the first
* character mismatch between extended_name and entry.
* If we shorten it back to the prefix length, stop searching.
*/
recognize(extended_name, entry, name_length, numitems)
tchar *extended_name, *entry;
{
#ifdef TRACE
tprintf("TRACE- recognize()\n");
#endif
if (numitems == 1) /* 1st match */
copyn(extended_name, entry, MAXNAMLEN);
else { /* 2nd and subsequent matches */
register tchar *x, *ent;
register int len = 0;
x = extended_name;
for (ent = entry; *x && *x == *ent++; x++, len++)
;
*x = '\0'; /* Shorten at 1st char diff */
if (len == name_length) /* Ambiguous to prefix? */
return (-1); /* So stop now and save time */
}
return (0);
}
/*
* Return true if check items initial chars in template
* This differs from PWB imatch in that if check is null
* it items anything
*/
static
is_prefix(check, template)
register tchar *check, *template;
{
#ifdef TRACE
tprintf("TRACE- is_prefix()\n");
#endif
do
if (*check == 0)
return (TRUE);
while (*check++ == *template++);
return (FALSE);
}
/*
* Return true if the chars in template appear at the
* end of check, i.e., are its suffix.
*/
static
is_suffix(check, template)
tchar *check, *template;
{
register tchar *c, *t;
#ifdef TRACE
tprintf("TRACE- is_suffix()\n");
#endif
for (c = check; *c++;)
;
for (t = template; *t++;)
;
for (;;) {
if (t == template)
return (TRUE);
if (c == check || *--t != *--c)
return (FALSE);
}
}
tenex(inputline, inputline_size)
tchar *inputline;
int inputline_size;
{
register int numitems, num_read, should_retype;
int i;
#ifdef TRACE
tprintf("TRACE- tenex()\n");
#endif
setup_tty(ON);
termchars();
num_read = 0;
should_retype = FALSE;
while ((i = read_(SHIN, inputline+num_read, inputline_size-num_read))
> 0) {
static tchar *delims = S_DELIM /*" '\"\t;&<>()|`"*/;
register tchar *str_end, *word_start, last_char;
register int space_left;
struct termios tty;
COMMAND command;
num_read += i;
inputline[num_read] = '\0';
last_char = inputline[num_read - 1] & TRIM;
if ((num_read == inputline_size) || (last_char == '\n'))
break;
str_end = &inputline[num_read];
if (last_char == ESC) {
command = RECOGNIZE;
*--str_end = '\0'; /* wipe out trailing ESC */
} else {
command = LIST;
}
tty = tty_new;
tty.c_lflag &= ~ECHO;
(void) ioctl(SHIN, TCSETSF, (char *)&tty);
if (command == LIST)
putchar ('\n');
/*
* Find LAST occurence of a delimiter in the inputline.
* The word start is one character past it.
*/
for (word_start = str_end; word_start > inputline; --word_start)
if (index_(delims, word_start[-1])||isauxsp(word_start[-1]))
break;
space_left = inputline_size - (word_start - inputline) - 1;
numitems = search2(word_start, command, space_left);
if (command == RECOGNIZE) {
/* print from str_end on */
print_recognized_stuff(str_end);
if (numitems != 1) /* Beep = No match/ambiguous */
beep();
}
/*
* Tabs in the input line cause trouble after a pushback.
* tty driver won't backspace over them because column
* positions are now incorrect. This is solved by retyping
* over current line.
*/
if (index_(inputline, '\t')) { /* tab tchar in input line? */
back_to_col_1();
should_retype = TRUE;
}
if (command == LIST) /* Always retype after a LIST */
should_retype = TRUE;
if (should_retype)
printprompt();
pushback(inputline, should_retype);
num_read = 0; /* chars will be reread */
should_retype = FALSE;
}
setup_tty(OFF);
return (num_read);
}
static
ignored(entry)
register tchar *entry;
{
struct varent *vp;
register tchar **cp;
#ifdef TRACE
tprintf("TRACE- ignored()\n");
#endif
if ((vp = adrof(S_fignore /*"fignore"*/)) == NULL || (cp = vp->vec) == NULL)
return (FALSE);
for (; *cp != NULL; cp++)
if (is_suffix(entry, *cp))
return (TRUE);
return (FALSE);
}
#endif FILEC

1386
bin/csh/sh.func.c Normal file

File diff suppressed because it is too large Load Diff

857
bin/csh/sh.glob.c Normal file
View File

@@ -0,0 +1,857 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.glob.c 1.1 92/07/30 SMI; from UCB 5.4 5/13/86";
#endif
#include "sh.h"
#include <sys/dir.h>
#include "sh.tconst.h"
#ifdef MBCHAR
#include <widec.h> /* wcsetno() */
#endif /*MBCHAR*/
/*
* C Shell
*/
int globcnt;
tchar *gpath, *gpathp, *lastgpathp;
int globbed;
bool noglob;
bool nonomatch;
tchar *entp;
tchar **sortbas;
int sortscmp();
extern DIR *opendir_();
#define sort() qsort( (tchar *)sortbas, &gargv[gargc] - sortbas, \
sizeof(*sortbas), sortscmp), sortbas = &gargv[gargc]
tchar **
glob(v)
register tchar **v;
{
tchar agpath[BUFSIZ];
tchar *agargv[GAVSIZ];
gpath = agpath; gpathp = gpath; *gpathp = 0;
lastgpathp = &gpath[BUFSIZ - 2];
ginit(agargv); globcnt = 0;
#ifdef TRACE
tprintf("TRACE- glob()\n");
#endif
#ifdef GDEBUG
printf("glob entered: "); blkpr(v); printf("\n");
#endif
noglob = adrof(S_noglob /*"noglob"*/) != 0;
nonomatch = adrof(S_nonomatch /*"nonomatch"*/) != 0;
globcnt = noglob | nonomatch;
while (*v)
collect(*v++);
#ifdef GDEBUG
printf("glob done, globcnt=%d, gflag=%d: ", globcnt, gflag); blkpr(gargv); printf("\n");
#endif
if (globcnt == 0 && (gflag&1)) {
blkfree(gargv), gargv = 0;
return (0);
} else
return (gargv = copyblk(gargv));
}
ginit(agargv)
tchar **agargv;
{
agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
gnleft = NCARGS - 4;
}
collect(as)
register tchar *as;
{
register int i;
#ifdef TRACE
tprintf("TRACE- collect()\n");
#endif
if (any('`', as)) {
#ifdef GDEBUG
printf("doing backp of %s\n", as);
#endif
(void) dobackp(as, 0);
#ifdef GDEBUG
printf("backp done, acollect'ing\n");
#endif
for (i = 0; i < pargc; i++)
if (noglob) {
Gcat(pargv[i], S_ /*""*/);
sortbas = &gargv[gargc];
} else
acollect(pargv[i]);
if (pargv)
blkfree(pargv), pargv = 0;
#ifdef GDEBUG
printf("acollect done\n");
#endif
} else if (noglob || eq(as, S_LBRA /*"{" */) || eq(as, S_BRABRA /*"{}"*/)) {
Gcat(as, S_ /*""*/);
sort();
} else
acollect(as);
}
acollect(as)
register tchar *as;
{
register long ogargc = gargc;
#ifdef TRACE
tprintf("TRACE- acollect()\n");
#endif
gpathp = gpath; *gpathp = 0; globbed = 0;
expand(as);
if (gargc == ogargc) {
if (nonomatch) {
Gcat(as, S_ /*""*/);
sort();
}
} else
sort();
}
/*
* String compare for qsort. Also used by filec code in sh.file.c.
*/
sortscmp(a1, a2)
tchar **a1, **a2;
{
return (strcmp_(*a1, *a2));
}
expand(as)
tchar *as;
{
register tchar *cs;
register tchar *sgpathp, *oldcs;
struct stat stb;
#ifdef TRACE
tprintf("TRACE- expand()\n");
#endif
sgpathp = gpathp;
cs = as;
if (*cs == '~' && gpathp == gpath) {
addpath('~');
for (cs++; alnum(*cs) || *cs == '-';)
addpath(*cs++);
if (!*cs || *cs == '/') {
if (gpathp != gpath + 1) {
*gpathp = 0;
if (gethdir(gpath + 1))
/*
* modified from %s to %t
*/
error("Unknown user: %t", gpath + 1);
(void) strcpy_(gpath, gpath + 1);
} else
(void) strcpy_(gpath, value(S_home /*"home" */));
gpathp = strend(gpath);
}
}
while (!isglob(*cs)) {
if (*cs == 0) {
if (!globbed)
Gcat(gpath, S_ /*"" */);
else if (stat_(gpath, &stb) >= 0) {
Gcat(gpath, S_ /*""*/);
globcnt++;
}
goto endit;
}
addpath(*cs++);
}
oldcs = cs;
while (cs > as && *cs != '/')
cs--, gpathp--;
if (*cs == '/')
cs++, gpathp++;
*gpathp = 0;
if (*oldcs == '{') {
(void) execbrc(cs, NOSTR);
return;
}
matchdir_(cs);
endit:
gpathp = sgpathp;
*gpathp = 0;
}
matchdir_(pattern)
tchar *pattern;
{
struct stat stb;
register struct direct *dp;
register DIR *dirp;
tchar curdir_[MAXNAMLEN+1];
#ifdef TRACE
tprintf("TRACE- matchdir()\n");
#endif
dirp = opendir_(gpath);
if (dirp == NULL) {
if (globbed)
return;
goto patherr2;
}
if (fstat(dirp->dd_fd, &stb) < 0)
goto patherr1;
if (!isdir(stb)) {
errno = ENOTDIR;
goto patherr1;
}
while ((dp = readdir(dirp)) != NULL) {
if (dp->d_ino == 0)
continue;
strtots(curdir_, dp->d_name);
if (match(curdir_, pattern)) {
Gcat(gpath, curdir_);
globcnt++;
}
}
closedir(dirp);
return;
patherr1:
closedir(dirp);
patherr2:
Perror(gpath);
}
execbrc(p, s)
tchar *p, *s;
{
tchar restbuf[BUFSIZ + 2];
register tchar *pe, *pm, *pl;
int brclev = 0;
tchar *lm, savec, *sgpathp;
#ifdef TRACE
tprintf("TRACE- execbrc()\n");
#endif
for (lm = restbuf; *p != '{'; *lm++ = *p++)
continue;
for (pe = ++p; *pe; pe++)
switch (*pe) {
case '{':
brclev++;
continue;
case '}':
if (brclev == 0)
goto pend;
brclev--;
continue;
case '[':
for (pe++; *pe && *pe != ']'; pe++)
continue;
if (!*pe)
error("Missing ]");
continue;
}
pend:
if (brclev || !*pe)
error("Missing }");
for (pl = pm = p; pm <= pe; pm++)
switch (*pm & (QUOTE|TRIM)) {
case '{':
brclev++;
continue;
case '}':
if (brclev) {
brclev--;
continue;
}
goto doit;
case ',':
if (brclev)
continue;
doit:
savec = *pm;
*pm = 0;
(void) strcpy_(lm, pl);
(void) strcat_(restbuf, pe + 1);
*pm = savec;
if (s == 0) {
sgpathp = gpathp;
expand(restbuf);
gpathp = sgpathp;
*gpathp = 0;
} else if (amatch(s, restbuf))
return (1);
sort();
pl = pm + 1;
continue;
case '[':
for (pm++; *pm && *pm != ']'; pm++)
continue;
if (!*pm)
error("Missing ]");
continue;
}
return (0);
}
match(s, p)
tchar *s, *p;
{
register int c;
register tchar *sentp;
tchar sglobbed = globbed;
#ifdef TRACE
tprintf("TRACE- match()\n");
#endif
if (*s == '.' && *p != '.')
return (0);
sentp = entp;
entp = s;
c = amatch(s, p);
entp = sentp;
globbed = sglobbed;
return (c);
}
amatch(s, p)
register tchar *s, *p;
{
register int scc;
int ok, lc;
tchar *sgpathp;
struct stat stb;
int c, cc;
#ifdef TRACE
tprintf("TRACE- amatch()\n");
#endif
globbed = 1;
for (;;) {
scc = *s++ & TRIM;
switch (c = *p++) {
case '{':
return (execbrc(p - 1, s - 1));
case '[':
ok = 0;
lc = TRIM;
while (cc = *p++) {
if (cc == ']') {
if (ok)
break;
return (0);
}
if (cc == '-') {
#ifdef MBCHAR
wchar_t rc= *p++;
/* Both ends of the char range
* must belong to the same codeset...
*/
if(wcsetno((wchar_t)lc)!=
wcsetno((wchar_t)rc)){
/* But if not, we quietly
* ignore the '-' operator.
* [x-y] is treated as if
* it were [xy].
*/
if (scc == (lc = rc))
ok++;
}
if (lc <= scc && scc <= rc
&& wcsetno(lc)==wcsetno(scc))
ok++;
#else /*!MBCHAR*/
if (lc <= scc && scc <= *p++)
ok++;
#endif /*!MBCHAR */
} else
if (scc == (lc = cc))
ok++;
}
if (cc == 0)
error("Missing ]");
continue;
case '*':
if (!*p)
return (1);
if (*p == '/') {
p++;
goto slash;
}
for (s--; *s; s++)
if (amatch(s, p))
return (1);
return (0);
case 0:
return (scc == 0);
default:
if ((c & TRIM) != scc)
return (0);
continue;
case '?':
if (scc == 0)
return (0);
continue;
case '/':
if (scc)
return (0);
slash:
s = entp;
sgpathp = gpathp;
while (*s)
addpath(*s++);
addpath('/');
if (stat_(gpath, &stb) == 0 && isdir(stb))
if (*p == 0) {
Gcat(gpath, S_ /*""*/);
globcnt++;
} else
expand(p);
gpathp = sgpathp;
*gpathp = 0;
return (0);
}
}
}
Gmatch(s, p)
register tchar *s, *p;
{
register int scc;
int ok, lc;
int c, cc;
#ifdef TRACE
tprintf("TRACE- Gmatch()\n");
#endif
for (;;) {
scc = *s++ & TRIM;
switch (c = *p++) {
case '[':
ok = 0;
lc = TRIM;
while (cc = *p++) {
if (cc == ']') {
if (ok)
break;
return (0);
}
if (cc == '-') {
#ifdef MBCHAR
wchar_t rc= *p++;
/* Both ends of the char range
* must belong to the same codeset...
*/
if(wcsetno((wchar_t)lc)!=
wcsetno((wchar_t)rc)){
/* But if not, we quietly
* ignore the '-' operator.
* [x-y] is treated as if
* it were [xy].
*/
if (scc == (lc = rc))
ok++;
}
if (lc <= scc && scc <= rc
&& wcsetno(lc)==wcsetno(scc))
ok++;
#else /*!MBCHAR*/
if (lc <= scc && scc <= *p++)
ok++;
#endif /*!MBCHAR*/
} else
if (scc == (lc = cc))
ok++;
}
if (cc == 0)
bferr("Missing ]");
continue;
case '*':
if (!*p)
return (1);
for (s--; *s; s++)
if (Gmatch(s, p))
return (1);
return (0);
case 0:
return (scc == 0);
default:
if ((c & TRIM) != scc)
return (0);
continue;
case '?':
if (scc == 0)
return (0);
continue;
}
}
}
Gcat(s1, s2)
tchar *s1, *s2;
{
register tchar *p, *q;
int n;
#ifdef TRACE
tprintf("TRACE- Gcat()\n");
#endif
for (p = s1; *p++;)
;
for (q = s2; *q++;)
;
gnleft -= (n = (p - s1) + (q - s2) - 1);
if (gnleft <= 0 || ++gargc >= GAVSIZ)
error("Arguments too long");
gargv[gargc] = 0;
p = gargv[gargc - 1] = (tchar *)xalloc((unsigned)n*sizeof(tchar));
for (q = s1; *p++ = *q++;)
;
for (p--, q = s2; *p++ = *q++;)
;
}
addpath(c)
tchar c;
{
#ifdef TRACE
tprintf("TRACE- addpath()\n");
#endif
if (gpathp >= lastgpathp)
error("Pathname too long");
*gpathp++ = c & TRIM;
*gpathp = 0;
}
rscan(t, f)
register tchar **t;
int (*f)();
{
register tchar *p;
#ifdef TRACE
tprintf("TRACE- rscan()\n");
#endif
while (p = *t++)
while (*p)
(*f)(*p++);
}
trim(t)
register tchar **t;
{
register tchar *p;
#ifdef TRACE
tprintf("TRACE- trim()\n");
#endif
while (p = *t++)
while (*p)
*p++ &= TRIM;
}
tglob(t)
register tchar **t;
{
register tchar *p, c;
#ifdef TRACE
tprintf("TRACE- tglob()\n");
#endif
while (p = *t++) {
if (*p == '~')
gflag |= 2;
else if (*p == '{' && (p[1] == '\0' || p[1] == '}' && p[2] == '\0'))
continue;
while (c = *p++)
if (isglob(c))
gflag |= c == '{' ? 2 : 1;
}
}
tchar *
globone(str)
register tchar *str;
{
tchar *gv[2];
register tchar **gvp;
register tchar *cp;
#ifdef TRACE
tprintf("TRACE- globone()\n");
#endif
gv[0] = str;
gv[1] = 0;
gflag = 0;
tglob(gv);
if (gflag) {
gvp = glob(gv);
if (gvp == 0) {
setname(str);
bferr("No match");
}
cp = *gvp++;
if (cp == 0)
cp = S_ /*""*/;
else if (*gvp) {
setname(str);
bferr("Ambiguous");
} else
cp = strip(cp);
/*
if (cp == 0 || *gvp) {
setname(str);
bferr(cp ? "Ambiguous" : "No output");
}
*/
xfree( (char *)gargv); gargv = 0;
} else {
trim(gv);
cp = savestr(gv[0]);
}
return (cp);
}
/*
* Command substitute cp. If literal, then this is
* a substitution from a << redirection, and so we should
* not crunch blanks and tabs, separating words only at newlines.
*/
tchar **
dobackp(cp, literal)
tchar *cp;
bool literal;
{
register tchar *lp, *rp;
tchar *ep;
tchar word[BUFSIZ];
tchar *apargv[GAVSIZ + 2];
#ifdef TRACE
tprintf("TRACE- dobackp()\n");
#endif
if (pargv) {
abort();
blkfree(pargv);
}
pargv = apargv;
pargv[0] = NOSTR;
pargcp = pargs = word;
pargc = 0;
pnleft = BUFSIZ - 4;
for (;;) {
for (lp = cp; *lp != '`'; lp++) {
if (*lp == 0) {
if (pargcp != pargs)
pword();
#ifdef GDEBUG
printf("leaving dobackp\n");
#endif
return (pargv = copyblk(pargv));
}
psave(*lp);
}
lp++;
for (rp = lp; *rp && *rp != '`'; rp++)
if (*rp == '\\') {
rp++;
if (!*rp)
goto oops;
}
if (!*rp)
oops:
error("Unmatched `");
ep = savestr(lp);
ep[rp - lp] = 0;
backeval(ep, literal);
#ifdef GDEBUG
printf("back from backeval\n");
#endif
cp = rp + 1;
}
}
backeval(cp, literal)
tchar *cp;
bool literal;
{
int pvec[2];
int quoted = (literal || (cp[0] & QUOTE)) ? QUOTE : 0;
tchar ibuf[BUFSIZ];
register int icnt = 0, c;
register tchar *ip;
bool hadnl = 0;
tchar *fakecom[2];
struct command faket;
#ifdef TRACE
tprintf("TRACE- backeval()\n");
#endif
faket.t_dtyp = TCOM;
faket.t_dflg = 0;
faket.t_dlef = 0;
faket.t_drit = 0;
faket.t_dspr = 0;
faket.t_dcom = fakecom;
fakecom[0] = S_QPPPQ; /*"` ... `"*/;
fakecom[1] = 0;
/*
* We do the psave job to temporarily change the current job
* so that the following fork is considered a separate job.
* This is so that when backquotes are used in a
* builtin function that calls glob the "current job" is not corrupted.
* We only need one level of pushed jobs as long as we are sure to
* fork here.
*/
psavejob();
/*
* It would be nicer if we could integrate this redirection more
* with the routines in sh.sem.c by doing a fake execute on a builtin
* function that was piped out.
*/
mypipe(pvec);
if (pfork(&faket, -1) == 0) {
struct wordent paraml;
struct command *t;
(void) close(pvec[0]);
(void) dmove(pvec[1], 1);
(void) dmove(SHDIAG, 2);
initdesc();
arginp = cp;
while (*cp)
*cp++ &= TRIM;
(void) lex(&paraml);
if (err)
error(err);
alias(&paraml);
t = syntax(paraml.next, &paraml, 0);
if (err)
error(err);
if (t)
t->t_dflg |= FPAR;
(void) signal(SIGTSTP, SIG_IGN);
(void) signal(SIGTTIN, SIG_IGN);
(void) signal(SIGTTOU, SIG_IGN);
execute(t, -1);
exitstat();
}
xfree(cp);
(void) close(pvec[1]);
do {
int cnt = 0;
for (;;) {
if (icnt == 0) {
ip = ibuf;
icnt = read_(pvec[0], ip, BUFSIZ);
if (icnt <= 0) {
c = -1;
break;
}
}
if (hadnl)
break;
--icnt;
c = (*ip++ & TRIM);
if (c == 0)
break;
if (c == '\n') {
/*
* Continue around the loop one
* more time, so that we can eat
* the last newline without terminating
* this word.
*/
hadnl = 1;
continue;
}
if (!quoted && issp(c))
break;
cnt++;
psave(c | quoted);
}
/*
* Unless at end-of-file, we will form a new word
* here if there were characters in the word, or in
* any case when we take text literally. If
* we didn't make empty words here when literal was
* set then we would lose blank lines.
*/
if (c != -1 && (cnt || literal))
pword();
hadnl = 0;
} while (c >= 0);
#ifdef GDEBUG
printf("done in backeval, pvec: %d %d\n", pvec[0], pvec[1]);
printf("also c = %c <%o>\n", c, c);
#endif
(void) close(pvec[0]);
pwait();
prestjob();
}
psave(c)
tchar c;
{
#ifdef TRACE
tprintf("TRACE- psave()\n");
#endif
if (--pnleft <= 0)
error("Word too long");
*pargcp++ = c;
}
pword()
{
#ifdef TRACE
tprintf("TRACE- pword()\n");
#endif
psave(0);
if (pargc == GAVSIZ)
error("Too many words from ``");
pargv[pargc++] = savestr(pargs);
pargv[pargc] = NOSTR;
#ifdef GDEBUG
printf("got word %s\n", pargv[pargc-1]);
#endif
pargcp = pargs;
pnleft = BUFSIZ - 4;
}

533
bin/csh/sh.h Normal file
View File

@@ -0,0 +1,533 @@
/* @(#)sh.h 1.1 92/07/30 SMI; from UCB 5.3 3/29/86 */
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <errno.h>
#include <setjmp.h>
#include <vfork.h>
#include <stdlib.h> /* MB_xxx, mbxxx(), wcxxx() etc. */
#include <malloc.h>
#include "sh.local.h"
#include "sh.char.h"
#ifdef MBCHAR
# if !defined(MB_LEN_MAX) || !defined(MB_CUR_MAX)
Error: I need both ANSI macros!
# endif
#else
# if !defined(MB_LEN_MAX)
# define MB_LEN_MAX 1
# endif
# if !defined(MB_CUR_MAX)
# define MB_CUR_MAX 1
# endif
#endif
#ifndef MBCHAR /* Let's replace the ANSI functions with our own macro
* for efficiency!
*/
#define mbtowc(pwc, pmb, n_is_ignored) ((*(pwc)=*(pmb)), 1)
#define wctomb(pmb, wc) ((*(pmb)=((char)wc)), 1)
#endif/*!MBCHAR*/
/*
* C shell
*
* Bill Joy, UC Berkeley
* October, 1978; May 1980
*
* Jim Kulp, IIASA, Laxenburg Austria
* April, 1980
*/
#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR)
typedef char bool;
/* tchar (Tagged CHARacter) is a place holder to keep a QUOTE bit and
* a character.
* For European language handling, lower 8 bits of tchar is used
* to store a character. For other languages, especially Asian, 16 bits
* are used to store a character.
* Following typedef's assume short int is a 16-bit entity and long int is
* a 32-bit entity.
* The QUOTE bit tells whether the character is subject to further
* interpretation such as history substitution, file mathing, command
* subsitution. TRIM is a mask to strip off the QUOTE bit.
*/
#ifdef MBCHAR /* For multibyte character handling. */
typedef long int tchar;
#define QUOTE 0x80000000
#define TRIM 0x0000ffff
#else/*!MBCHAR*/ /* European language requires only 8 bits. */
typedef unsigned short int tchar;
#define QUOTE 0x8000
#define TRIM 0x00ff
#endif/*!MBCHAR*/
#define eq(a, b) (strcmp_(a, b) == 0)
/*
* Global flags
*/
bool chkstop; /* Warned of stopped jobs... allow exit */
bool didfds; /* Have setup i/o fd's for child */
bool doneinp; /* EOF indicator after reset from readc */
bool exiterr; /* Exit if error or non-zero exit status */
bool child; /* Child shell ... errors cause exit */
bool haderr; /* Reset was because of an error */
bool intty; /* Input is a tty */
bool intact; /* We are interactive... therefore prompt */
bool justpr; /* Just print because of :p hist mod */
bool loginsh; /* We are a loginsh -> .login/.logout */
bool neednote; /* Need to pnotify() */
bool noexec; /* Don't execute, just syntax check */
bool pjobs; /* want to print jobs if interrupted */
bool setintr; /* Set interrupts on/off -> Wait intr... */
bool timflg; /* Time the next waited for command */
bool havhash; /* path hashing is available */
#ifdef FILEC
bool filec; /* doing filename expansion */
#endif
/*
* Global i/o info
*/
tchar *arginp; /* Argument input for sh -c and internal `xx` */
int onelflg; /* 2 -> need line for -t, 1 -> exit on read */
tchar *file; /* Name of shell file for $0 */
char *err; /* Error message from scanner/parser */
int errno; /* Error from C library routines */
tchar *shtemp; /* Temp name for << shell files in /tmp */
struct timeval time0; /* Time at which the shell started */
struct rusage ru0;
/*
* Miscellany
*/
tchar *doldol; /* Character pid for $$ */
int uid; /* Invokers uid */
time_t chktim; /* Time mail last checked */
int shpgrp; /* Pgrp of shell */
int tpgrp; /* Terminal process group */
/* If tpgrp is -1, leave tty alone! */
int opgrp; /* Initial pgrp and tty pgrp */
int oldisc; /* Initial line discipline or -1 */
/*
* These are declared here because they want to be
* initialized in sh.init.c (to allow them to be made readonly)
*/
extern struct biltins {
tchar *bname;
int (*bfunct)();
short minargs, maxargs;
} bfunc[];
extern int nbfunc;
extern struct srch {
tchar *s_name;
short s_value;
} srchn[];
extern int nsrchn;
/*
* To be able to redirect i/o for builtins easily, the shell moves the i/o
* descriptors it uses away from 0,1,2.
* Ideally these should be in units which are closed across exec's
* (this saves work) but for version 6, this is not usually possible.
* The desired initial values for these descriptors are defined in
* sh.local.h.
*/
short SHIN; /* Current shell input (script) */
short SHOUT; /* Shell output */
short SHDIAG; /* Diagnostic output... shell errs go here */
short OLDSTD; /* Old standard input (def for cmds) */
/*
* Error control
*
* Errors in scanning and parsing set up an error message to be printed
* at the end and complete. Other errors always cause a reset.
* Because of source commands and .cshrc we need nested error catches.
*/
jmp_buf reslab;
#define setexit() ((void) setjmp(reslab))
#define reset() longjmp(reslab, 0)
/* Should use structure assignment here */
#define getexit(a) copy((void *)(a), (void *)reslab, sizeof reslab)
#define resexit(a) copy((void *)reslab, ((void *)(a)), sizeof reslab)
tchar *gointr; /* Label for an onintr transfer */
void (*parintr)(); /* Parents interrupt catch */
void (*parterm)(); /* Parents terminate catch */
/*
* Each level of input has a buffered input structure.
* There are one or more blocks of buffered input for each level,
* exactly one if the input is seekable and tell is available.
* In other cases, the shell buffers enough blocks to keep all loops
* in the buffer.
*/
struct Bin {
off_t Bfseekp; /* Seek pointer */
off_t Bfbobp; /* Seekp of beginning of buffers */
off_t Bfeobp; /* Seekp of end of buffers */
short Bfblocks; /* Number of buffer blocks */
tchar **Bfbuf; /* The array of buffer blocks */
} B;
#define fseekp B.Bfseekp
#define fbobp B.Bfbobp
#define feobp B.Bfeobp
#define fblocks B.Bfblocks
#define fbuf B.Bfbuf
#define btell() fseekp
#ifndef btell
off_t btell();
#endif
/*
* The shell finds commands in loops by reseeking the input
* For whiles, in particular, it reseeks to the beginning of the
* line the while was on; hence the while placement restrictions.
*/
off_t lineloc;
#ifdef TELL
bool cantell; /* Is current source tellable ? */
#endif
/*
* Input lines are parsed into doubly linked circular
* lists of words of the following form.
*/
struct wordent {
tchar *word;
struct wordent *prev;
struct wordent *next;
};
/*
* During word building, both in the initial lexical phase and
* when expanding $ variable substitutions, expansion by `!' and `$'
* must be inhibited when reading ahead in routines which are themselves
* processing `!' and `$' expansion or after characters such as `\' or in
* quotations. The following flags are passed to the getC routines
* telling them which of these substitutions are appropriate for the
* next character to be returned.
*/
#define DODOL 1
#define DOEXCL 2
#define DOALL DODOL|DOEXCL
/*
* Labuf implements a general buffer for lookahead during lexical operations.
* Text which is to be placed in the input stream can be stuck here.
* We stick parsed ahead $ constructs during initial input,
* process id's from `$$', and modified variable values (from qualifiers
* during expansion in sh.dol.c) here.
*/
tchar labuf[BUFSIZ];
tchar *lap;
/*
* Parser structure
*
* Each command is parsed to a tree of command structures and
* flags are set bottom up during this process, to be propagated down
* as needed during the semantics/exeuction pass (sh.sem.c).
*/
struct command {
short t_dtyp; /* Type of node */
short t_dflg; /* Flags, e.g. FAND|... */
union {
tchar *T_dlef; /* Input redirect word */
struct command *T_dcar; /* Left part of list/pipe */
} L;
union {
tchar *T_drit; /* Output redirect word */
struct command *T_dcdr; /* Right part of list/pipe */
} R;
#define t_dlef L.T_dlef
#define t_dcar L.T_dcar
#define t_drit R.T_drit
#define t_dcdr R.T_dcdr
tchar **t_dcom; /* Command/argument vector */
char *cfname; /* char pathname for execv */
char **cargs; /* char arg vec for execv */
struct command *t_dspr; /* Pointer to ()'d subtree */
short t_nice;
};
#define TCOM 1 /* t_dcom <t_dlef >t_drit */
#define TPAR 2 /* ( t_dspr ) <t_dlef >t_drit */
#define TFIL 3 /* t_dlef | t_drit */
#define TLST 4 /* t_dlef ; t_drit */
#define TOR 5 /* t_dlef || t_drit */
#define TAND 6 /* t_dlef && t_drit */
#define FSAVE (FNICE|FTIME|FNOHUP) /* save these when re-doing */
#define FAND (1<<0) /* executes in background */
#define FCAT (1<<1) /* output is redirected >> */
#define FPIN (1<<2) /* input is a pipe */
#define FPOU (1<<3) /* output is a pipe */
#define FPAR (1<<4) /* don't fork, last ()ized cmd */
#define FINT (1<<5) /* should be immune from intr's */
/* spare */
#define FDIAG (1<<7) /* redirect unit 2 with unit 1 */
#define FANY (1<<8) /* output was ! */
#define FHERE (1<<9) /* input redirection is << */
#define FREDO (1<<10) /* reexec aft if, repeat,... */
#define FNICE (1<<11) /* t_nice is meaningful */
#define FNOHUP (1<<12) /* nohup this command */
#define FTIME (1<<13) /* time this command */
/*
* The keywords for the parser
*/
#define ZBREAK 0
#define ZBRKSW 1
#define ZCASE 2
#define ZDEFAULT 3
#define ZELSE 4
#define ZEND 5
#define ZENDIF 6
#define ZENDSW 7
#define ZEXIT 8
#define ZFOREACH 9
#define ZGOTO 10
#define ZIF 11
#define ZLABEL 12
#define ZLET 13
#define ZSET 14
#define ZSWITCH 15
#define ZTEST 16
#define ZTHEN 17
#define ZWHILE 18
/*
* Structure defining the existing while/foreach loops at this
* source level. Loops are implemented by seeking back in the
* input. For foreach (fe), the word list is attached here.
*/
struct whyle {
off_t w_start; /* Point to restart loop */
off_t w_end; /* End of loop (0 if unknown) */
tchar **w_fe, **w_fe0; /* Current/initial wordlist for fe */
tchar *w_fename; /* Name for fe */
struct whyle *w_next; /* Next (more outer) loop */
} *whyles;
/*
* Variable structure
*
* Aliases and variables are stored in AVL balanced binary trees.
*/
struct varent {
tchar **vec; /* Array of words which is the value */
tchar *v_name; /* Name of variable/alias */
struct varent *v_link[3]; /* The links, see below */
int v_bal; /* Balance factor */
} shvhed, aliases;
#define v_left v_link[0]
#define v_right v_link[1]
#define v_parent v_link[2]
struct varent *adrof1();
#define adrof(v) adrof1(v, &shvhed)
#define value(v) value1(v, &shvhed)
/*
* The following are for interfacing redo substitution in
* aliases to the lexical routines.
*/
struct wordent *alhistp; /* Argument list (first) */
struct wordent *alhistt; /* Node after last in arg list */
tchar **alvec; /* The (remnants of) alias vector */
/*
* Filename/command name expansion variables
*/
short gflag; /* After tglob -> is globbing needed? */
/*
* A reasonable limit on number of arguments would seem to be
* the maximum number of characters in an arg list / 6.
*
* XXX: With the new VM system, NCARGS has become enormous, making
* it impractical to allocate arrays with NCARGS / 6 entries on
* the stack. The proper fix is to revamp code elsewhere (in
* sh.dol.c and sh.glob.c) to use a different technique for handling
* command line arguments. In the meantime, we simply fall back
* on using the old value of NCARGS.
*/
#ifdef notyet
#define GAVSIZ (NCARGS / 6)
#else notyet
#define GAVSIZ (10240 / 6)
#endif notyet
/*
* Variables for filename expansion
*/
tchar **gargv; /* Pointer to the (stack) arglist */
long gargc; /* Number args in gargv */
long gnleft;
/*
* Variables for command expansion.
*/
tchar **pargv; /* Pointer to the argv list space */
tchar *pargs; /* Pointer to start current word */
long pargc; /* Count of arguments in pargv */
long pnleft; /* Number of chars left in pargs */
tchar *pargcp; /* Current index into pargs */
/*
* History list
*
* Each history list entry contains an embedded wordlist
* from the scanner, a number for the event, and a reference count
* to aid in discarding old entries.
*
* Essentially "invisible" entries are put on the history list
* when history substitution includes modifiers, and thrown away
* at the next discarding since their event numbers are very negative.
*/
struct Hist {
struct wordent Hlex;
int Hnum;
int Href;
struct Hist *Hnext;
} Histlist;
struct wordent paraml; /* Current lexical word list */
int eventno; /* Next events number */
int lastev; /* Last event reference (default) */
tchar HIST; /* history invocation character */
tchar HISTSUB; /* auto-substitute character */
/*
* In lines for frequently called functions
*/
#define XFREE(cp) { \
extern char end[]; \
char stack; \
/*??*/ if (((char *)(cp)) >= end && ((char *)(cp)) < &stack) \
/*??*/ free((void *)cp); \
}
void *alloctmp;
#define xalloc(i) ((alloctmp = (void *)malloc(i)) ? alloctmp : (void *)nomem(i))/*??*/
tchar *Dfix1();
tchar **blkcat();
tchar **blkcpy();
tchar **blkend();
tchar **blkspl();
char **blkspl_();
tchar *cname();
tchar **copyblk();
tchar **dobackp();
tchar *domod();
struct wordent *dosub();
tchar *exp3();
tchar *exp3a();
tchar *exp4();
tchar *exp5();
tchar *exp6();
struct Hist *enthist();
struct Hist *findev();
struct wordent *freenod();
char *getenv();
tchar *getenv_(/* tchar * */);
tchar *getenvs_(/* char * */);
tchar *getinx();
struct varent *getvx();
struct passwd *getpwnam();
struct wordent *gethent();
struct wordent *getsub();
char *getwd();
tchar *getwd_();
tchar **glob();
tchar *globone();
char *index();
tchar *index_();
struct biltins *isbfunc();
off_t lseek();
tchar *operate();
void phup();
void pintr();
void pchild();
tchar *putn();
char *rindex();
tchar *rindex_();
tchar **saveblk();
tchar *savestr();
char *strcat();
tchar *strcat_();
char *strcpy();
tchar *strcpy_();
tchar *strend();
tchar *strip();
tchar *strspl();
tchar *subword();
struct command *syntax();
struct command *syn0();
struct command *syn1();
struct command *syn1a();
struct command *syn1b();
struct command *syn2();
struct command *syn3();
tchar *value1();
tchar *xhome();
tchar *xname();
tchar *xset();
#define NOSTR ((tchar *) 0)
/*
* setname is a macro to save space (see sh.err.c)
*/
tchar *bname;
#define setname(a) (bname = (a))
#ifdef VFORK
tchar *Vsav;
tchar **Vav;
tchar *Vdp;
#endif
tchar **evalvec;
tchar *evalp;
struct mesg {
tchar *iname; /* signal name from /usr/include */
char *pname; /* print name */
} mesg[];
/* Conversion functions between char and tchar strings. */
tchar *strtots(/* tchar * , char * */);
char *tstostr(/* char * , tchar * */);
#ifndef NULL
#define NULL 0
#endif

161
bin/csh/sh.hist.c Normal file
View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.hist.c 1.1 92/07/30 SMI; from UCB 5.2 6/6/85";
#endif
#include "sh.h"
#include "sh.tconst.h"
/*
* C shell
*/
savehist(sp)
struct wordent *sp;
{
register struct Hist *hp, *np;
register int histlen = 0;
tchar *cp;
#ifdef TRACE
tprintf("TRACE- savehist()\n");
#endif
/* throw away null lines */
if (sp->next->word[0] == '\n')
return;
cp = value(S_history /*"history"*/);
if (*cp) {
register tchar *p = cp;
while (*p) {
if (!digit(*p)) {
histlen = 0;
break;
}
histlen = histlen * 10 + *p++ - '0';
}
}
for (hp = &Histlist; np = hp->Hnext;)
if (eventno - np->Href >= histlen || histlen == 0)
hp->Hnext = np->Hnext, hfree(np);
else
hp = np;
(void) enthist(++eventno, sp, 1);
}
struct Hist *
enthist(event, lp, docopy)
int event;
register struct wordent *lp;
bool docopy;
{
register struct Hist *np;
#ifdef TRACE
tprintf("TRACE- enthist()\n");
#endif
np = (struct Hist *) xalloc(sizeof *np);
np->Hnum = np->Href = event;
if (docopy)
copylex(&np->Hlex, lp);
else {
np->Hlex.next = lp->next;
lp->next->prev = &np->Hlex;
np->Hlex.prev = lp->prev;
lp->prev->next = &np->Hlex;
}
np->Hnext = Histlist.Hnext;
Histlist.Hnext = np;
return (np);
}
hfree(hp)
register struct Hist *hp;
{
#ifdef TRACE
tprintf("TRACE- hfree()\n");
#endif
freelex(&hp->Hlex);
xfree( (tchar *)hp);
}
dohist(vp)
tchar **vp;
{
int n, rflg = 0, hflg = 0;
#ifdef TRACE
tprintf("TRACE- dohist()\n");
#endif
if (getn(value(S_history /*"history"*/)) == 0)
return;
if (setintr)
(void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
while (*++vp && **vp == '-') {
tchar *vp2 = *vp;
while (*++vp2)
switch (*vp2) {
case 'h':
hflg++;
break;
case 'r':
rflg++;
break;
case '-': /* ignore multiple '-'s */
break;
default:
printf("Unknown flag: -%c\n", *vp2);
error("Usage: history [-rh] [# number of events]");
}
}
if (*vp)
n = getn(*vp);
else {
n = getn(value(S_history /*"history"*/));
}
dohist1(Histlist.Hnext, &n, rflg, hflg);
}
dohist1(hp, np, rflg, hflg)
struct Hist *hp;
int *np, rflg, hflg;
{
bool print = (*np) > 0;
#ifdef TRACE
tprintf("TRACE- dohist1()\n");
#endif
top:
if (hp == 0)
return;
(*np)--;
hp->Href++;
if (rflg == 0) {
dohist1(hp->Hnext, np, rflg, hflg);
if (print)
phist(hp, hflg);
return;
}
if (*np >= 0)
phist(hp, hflg);
hp = hp->Hnext;
goto top;
}
phist(hp, hflg)
register struct Hist *hp;
int hflg;
{
#ifdef TRACE
tprintf("TRACE- phist()\n");
#endif
if (hflg == 0)
printf("%6d\t", hp->Hnum);
prlex(&hp->Hlex);
}

235
bin/csh/sh.init.c Normal file
View File

@@ -0,0 +1,235 @@
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
*/
#ifndef lint
static char *sccsid = "@(#)sh.init.c 1.1 92/07/30 SMI; from UCB 5.2 6/6/85";
#endif
#include "sh.h"
#include "sh.tconst.h"
/*
* C shell
*/
extern int doalias();
extern int dobg();
extern int dobreak();
extern int dochngd();
extern int docontin();
extern int dodirs();
extern int doecho();
extern int doelse();
extern int doend();
extern int doendif();
extern int doendsw();
extern int doeval();
extern int doexit();
extern int dofg();
extern int doforeach();
extern int doglob();
extern int dogoto();
extern int dohash();
extern int dohist();
extern int doif();
extern int dojobs();
extern int dokill();
extern int dolet();
extern int dolimit();
extern int dologin();
extern int dologout();
#ifdef NEWGRP
extern int donewgrp();
#endif
extern int donice();
extern int donotify();
extern int donohup();
extern int doonintr();
extern int dopopd();
extern int dopushd();
extern int dorepeat();
extern int doset();
extern int dosetenv();
extern int dosource();
extern int dostop();
extern int dosuspend();
extern int doswbrk();
extern int doswitch();
extern int dotime();
extern int dounlimit();
extern int doumask();
extern int dowait();
extern int dowhile();
extern int dozip();
extern int execash();
extern int goodbye();
#ifdef VFORK
extern int hashstat();
#endif
extern int shift();
#ifdef OLDMALLOC
extern int showall();
#endif
extern int unalias();
extern int dounhash();
extern int unset();
extern int dounsetenv();
#define INF 1000
struct biltins bfunc[] = {
S_AT, dolet, 0, INF,
S_alias, doalias, 0, INF,
#ifdef OLDMALLOC
S_alloc, showall, 0, 1,
#endif
S_bg, dobg, 0, INF,
S_break, dobreak, 0, 0,
S_breaksw, doswbrk, 0, 0,
#ifdef IIASA
S_bye, goodbye, 0, 0,
#endif
S_case, dozip, 0, 1,
S_cd, dochngd, 0, 1,
S_chdir, dochngd, 0, 1,
S_continue, docontin, 0, 0,
S_default, dozip, 0, 0,
S_dirs, dodirs, 0, 1,
S_echo, doecho, 0, INF,
S_else, doelse, 0, INF,
S_end, doend, 0, 0,
S_endif, dozip, 0, 0,
S_endsw, dozip, 0, 0,
S_eval, doeval, 0, INF,
S_exec, execash, 1, INF,
S_exit, doexit, 0, INF,
S_fg, dofg, 0, INF,
S_foreach, doforeach, 3, INF,
#ifdef IIASA
S_gd, dopushd, 0, 1,
#endif
S_glob, doglob, 0, INF,
S_goto, dogoto, 1, 1,
#ifdef VFORK
S_hashstat, hashstat, 0, 0,
#endif
S_history, dohist, 0, 2,
S_if, doif, 1, INF,
S_jobs, dojobs, 0, 1,
S_kill, dokill, 1, INF,
S_limit, dolimit, 0, 3,
S_login, dologin, 0, 1,
S_logout, dologout, 0, 0,
#ifdef NEWGRP
S_newgrp, donewgrp, 1, 1,
#endif
S_nice, donice, 0, INF,
S_nohup, donohup, 0, INF,
S_notify, donotify, 0, INF,
S_onintr, doonintr, 0, 2,
S_popd, dopopd, 0, 1,
S_pushd, dopushd, 0, 1,
#ifdef IIASA
S_rd, dopopd, 0, 1,
#endif
S_rehash, dohash, 0, 0,
S_repeat, dorepeat, 2, INF,
S_set, doset, 0, INF,
S_setenv, dosetenv, 0, 2,
S_shift, shift, 0, 1,
S_source, dosource, 1, 2,
S_stop, dostop, 1, INF,
S_suspend, dosuspend, 0, 0,
S_switch, doswitch, 1, INF,
S_time, dotime, 0, INF,
S_umask, doumask, 0, 1,
S_unalias, unalias, 1, INF,
S_unhash, dounhash, 0, 0,
S_unlimit, dounlimit, 0, INF,
S_unset, unset, 1, INF,
S_unsetenv, dounsetenv, 1, INF,
S_wait, dowait, 0, 0,
S_while, dowhile, 1, INF,
};
int nbfunc = sizeof bfunc / sizeof *bfunc;
#define ZBREAK 0
#define ZBRKSW 1
#define ZCASE 2
#define ZDEFAULT 3
#define ZELSE 4
#define ZEND 5
#define ZENDIF 6
#define ZENDSW 7
#define ZEXIT 8
#define ZFOREACH 9
#define ZGOTO 10
#define ZIF 11
#define ZLABEL 12
#define ZLET 13
#define ZSET 14
#define ZSWITCH 15
#define ZTEST 16
#define ZTHEN 17
#define ZWHILE 18
struct srch srchn[] = {
S_AT, ZLET,
S_break, ZBREAK,
S_breaksw, ZBRKSW,
S_case, ZCASE,
S_default, ZDEFAULT,
S_else, ZELSE,
S_end, ZEND,
S_endif, ZENDIF,
S_endsw, ZENDSW,
S_exit, ZEXIT,
S_foreach, ZFOREACH,
S_goto, ZGOTO,
S_if, ZIF,
S_label, ZLABEL,
S_set, ZSET,
S_switch, ZSWITCH,
S_while, ZWHILE
};
int nsrchn = sizeof srchn / sizeof *srchn;
struct mesg mesg[] = {
0, 0,
S_HUP, "Hangup",
S_INT, "Interrupt",
S_QUIT, "Quit",
S_ILL, "Illegal instruction",
S_TRAP, "Trace/BPT trap",
S_ABRT, "Abort",
S_EMT, "Emulator trap",
S_FPE, "Arithmetic exception",
S_KILL, "Killed",
S_BUS, "Bus error",
S_SEGV, "Segmentation fault",
S_SYS, "Bad system call",
S_PIPE, "Broken pipe",
S_ALRM, "Alarm clock",
S_TERM, "Terminated",
S_URG, "Urgent I/O condition",
S_STOP, "Stopped (signal)",
S_TSTP, "Stopped",
S_CONT, "Continued",
S_CHLD, "Child exited",
S_TTIN, "Stopped (tty input)",
S_TTOU, "Stopped (tty output)",
S_IO, "I/O possible",
S_XCPU, "Cputime limit exceeded",
S_XFSZ, "Filesize limit exceeded",
S_VTALRM,"Virtual timer expired",
S_PROF, "Profiling timer expired",
S_WINCH,"Window size changed",
S_LOST, "Resource lost",
S_USR1, "User defined signal 1",
S_USR2, "User defined signal 2",
0, "Signal 32"
};

Some files were not shown because too many files have changed in this diff Show More