Init
This commit is contained in:
78
5bin/Makefile
Normal file
78
5bin/Makefile
Normal 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
109
5bin/ar.sh
Normal 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
283
5bin/banner.c
Normal 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
450
5bin/cat.c
Normal 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
362
5bin/df.c
Normal 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
23
5bin/diff3/Makefile
Normal 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
23
5bin/diff3/diff3.sh
Normal 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
431
5bin/diff3/diff3prog.c
Normal 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
83
5bin/dircmp.sh
Normal 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
206
5bin/du.c
Normal 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 = ˙
|
||||
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
69
5bin/echo.c
Normal 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
413
5bin/expr.c
Normal 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
417
5bin/lint/sparc/Makefile
Normal 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
57
5bin/lint/sparc/align.h
Normal 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
155
5bin/ln.c
Normal 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
991
5bin/ls.c
Normal 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
24
5bin/m4/Makefile
Normal 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
851
5bin/m4/m4.c
Normal 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
96
5bin/m4/m4.h
Normal 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
94
5bin/m4/m4ext.c
Normal 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
535
5bin/m4/m4macs.c
Normal 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
131
5bin/m4/m4y.y
Normal 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
58
5bin/nohup.c
Normal 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 */
|
||||
}
|
||||
605
5bin/pr.c
Normal file
605
5bin/pr.c
Normal 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
32
5bin/sed/Makefile
Normal 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
133
5bin/sed/sed.h
Normal 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
847
5bin/sed/sed0.c
Normal 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
727
5bin/sed/sed1.c
Normal 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
85
5bin/sum.c
Normal 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
595
5bin/tabs.c
Normal 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
96
5bin/time.c
Normal 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
151
5bin/tr.c
Normal 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
48
5include/Makefile
Normal 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
13
5include/assert.h
Normal 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
74
5include/ctype.h
Normal 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
36
5include/grp.h
Normal 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
47
5include/malloc.h
Normal 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
57
5include/pwd.h
Normal 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
181
5include/stdio.h
Normal 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
49
5include/stdlib.h
Normal 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
10
5include/sys/Makefile
Normal 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
12
5include/sys/fcntl.h
Normal 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
58
5include/time.h
Normal 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
69
5lib/Makefile
Normal 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
399
5lib/compile/Makefile
Normal 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
41
Copyright
Normal 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
437
Makefile
Normal 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
18
Makefile.inter
Normal 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
11
README
Normal 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
13389
SIDlist/4.1.3.SID
Normal file
File diff suppressed because it is too large
Load Diff
6
_make
Normal file
6
_make
Normal 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
19
adm/Makefile
Normal 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
256
bin/Makefile
Normal 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
52
bin/arch.sh
Normal 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
63
bin/awk/Makefile
Normal 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
127
bin/awk/awk.def
Normal 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
277
bin/awk/awk.g.y
Normal 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
181
bin/awk/awk.lx.l
Normal 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
539
bin/awk/b.c
Normal 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
36
bin/awk/freeze.c
Normal 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
309
bin/awk/lib.c
Normal 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
100
bin/awk/main.c
Normal 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
96
bin/awk/makeprctab.c
Normal 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
169
bin/awk/parse.c
Normal 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
968
bin/awk/run.c
Normal 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
26
bin/awk/token.c
Normal 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
8
bin/awk/tokenscript
Normal 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
277
bin/awk/tran.c
Normal 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
|
||||
806
bin/cc.c
Normal file
806
bin/cc.c
Normal 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
216
bin/chgrp.c
Normal 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
265
bin/cmp.c
Normal 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
433
bin/cp.c
Normal 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
83
bin/csh/Makefile
Normal 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
27
bin/csh/README
Normal 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
396
bin/csh/alloc.c
Normal 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
475
bin/csh/doprnt.c
Normal 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
|
||||
11
bin/csh/make.sh.tconst.h.ed
Normal file
11
bin/csh/make.sh.tconst.h.ed
Normal 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
193
bin/csh/malloc.c
Normal 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
40
bin/csh/param.h
Normal 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
694
bin/csh/printf.c
Normal 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
44
bin/csh/printf.c.vax
Normal 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
458
bin/csh/sh.8bit.c
Normal 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
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
109
bin/csh/sh.char.c
Normal 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
57
bin/csh/sh.char.h
Normal 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"E)&&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
52
bin/csh/sh.debug.c
Normal 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
612
bin/csh/sh.dir.c
Normal 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
18
bin/csh/sh.dir.h
Normal 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
737
bin/csh/sh.dol.c
Normal 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
173
bin/csh/sh.err.c
Normal 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
439
bin/csh/sh.exec.c
Normal 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
655
bin/csh/sh.exp.c
Normal 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 = ¶ml;
|
||||
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(¶ml);
|
||||
t = syntax(paraml.next, ¶ml, 0);
|
||||
if (err)
|
||||
error(err);
|
||||
execute(t, -1);
|
||||
freelex(¶ml), 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
780
bin/csh/sh.file.c
Normal 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
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
857
bin/csh/sh.glob.c
Normal 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(¶ml);
|
||||
if (err)
|
||||
error(err);
|
||||
alias(¶ml);
|
||||
t = syntax(paraml.next, ¶ml, 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
533
bin/csh/sh.h
Normal 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
161
bin/csh/sh.hist.c
Normal 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
235
bin/csh/sh.init.c
Normal 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
Reference in New Issue
Block a user