561 lines · 8.9 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* POSIX DEPENDENT PROCEDURES */#include "defs.h"#include <sys/stat.h>#include <ar.h> #define NAMESPERBLOCK	32 /* DEFAULT RULES FOR POSIX */ char *dfltmacro[] =	{	".SUFFIXES : .o .c .y .l .a .sh .f",	"MAKE=make",	"AR=ar",	"ARFLAGS=rv",	"YACC=yacc",	"YFLAGS=",	"LEX=lex",	"LFLAGS=",	"LDFLAGS=",	"CC=c89",	"CFLAGS=-O",	"FC=fort77",	"FFLAGS=-O 1",	0 }; char *dfltpat[] =	{	"%.o : %.c",	"\t$(CC) $(CFLAGS) -c $<", 	"%.o : %.y",	"\t$(YACC) $(YFLAGS) $<",	"\t$(CC) $(CFLAGS) -c y.tab.c",	"\trm y.tab.c",	"\tmv y.tab.o $@", 	"%.o : %.l",	"\t$(LEX) $(LFLAGS) $<",	"\t$(CC) $(CFLAGS) -c lex.yy.c",	"\trm lex.yy.c",	"\tmv lex.yy.o $@", 	"%.c : %.y",	"\t$(YACC) $(YFLAGS) $<",	"\tmv y.tab.c $@", 	"%.c : %.l",	"\t$(LEX) $(LFLAGS) $<",	"\tmv lex.yy.c $@", 	"% : %.o",	"\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<", 	"% : %.c",	"\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<", 	0 };   char *dfltsuff[] =	{	".SUFFIXES : .o .c .y .l .a .sh .f",	".c.o :",	"\t$(CC) $(CFLAGS) -c $<", 	".f.o :",	"\t$(FC) $(FFLAGS) -c $<", 	".y.o :",	"\t$(YACC) $(YFLAGS) $<",	"\t$(CC) $(CFLAGS) -c y.tab.c",	"\trm -f y.tab.c",	"\tmv y.tab.o $@", 	".l.o :",	"\t$(LEX) $(LFLAGS) $<",	"\t$(CC) $(CFLAGS) -c lex.yy.c",	"\trm -f lex.yy.c",	"\tmv lex.yy.o $@", 	".y.c :",	"\t$(YACC) $(YFLAGS) $<",	"\tmv y.tab.c $@", 	".l.c :",	"\t$(LEX) $(LFLAGS) $<",	"\tmv lex.yy.c $@", 	".c.a:",	"\t$(CC) -c $(CFLAGS) $<",	"\t$(AR) $(ARFLAGS) $@ $*.o",	"\trm -f $*.o", 	".f.a:",	"\t$(FC) -c $(FFLAGS) $<",	"\t$(AR) $(ARFLAGS) $@ $*.o",	"\trm -f $*.o", 	".c:",	"\t$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<", 	".f:",	"\t$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<", 	".sh:",	"\tcp $< $@",	"\tchmod a+x $@", 	0 };  static struct dirhd	*opdir(char *, int);static void		cldir(struct dirhd *, int);static int		amatch(char *, char *);static int		umatch(char *, char *);static void		clarch(void);static int		openarch(char *);static int		getarch(void); time_texists(char *filename){struct stat buf;char *s; for(s = filename ; *s!='\0' && *s!='(' &&  *s!=')' ; ++s)	; if(*s != '\0')	return lookarch(filename); if(stat(filename,&buf) < 0) 	return 0;else	return buf.st_mtime;}  time_tprestime(void){time_t t;time(&t);return t;} static char nmtemp[MAXNAMLEN+1];	/* guarantees a null after the name */static char *tempend = nmtemp + MAXNAMLEN;   depblkpsrchdir(char *pat, int mkchain, depblkp nextdbl){DIR *dirf;struct dirhd *dirptr;char *dirname, *dirpref, *endir, *filepat, *p, temp[100];char fullname[100];nameblkp q;depblkp thisdbl;struct pattern *patp; struct dirent *dptr; thisdbl = 0; if(mkchain == NO)	for(patp=firstpat ; patp ; patp = patp->nxtpattern)		if(equal(pat, patp->patval)) return 0; patp = ALLOC(pattern);patp->nxtpattern = firstpat;firstpat = patp;patp->patval = copys(pat); endir = 0; for(p=pat; *p!='\0'; ++p)	if(*p=='/') endir = p; if(endir==0)	{	dirname = ".";	dirpref = "";	filepat = pat;	}else	{	dirname = pat;	*endir = '\0';	dirpref = concat(dirname, "/", temp);	filepat = endir+1;	} dirptr = opdir(dirname,YES);dirf = dirptr->dirfc; for( dptr = readdir(dirf) ; dptr ; dptr = readdir(dirf) )	{	char *p1, *p2;	p1 = dptr->d_name;	p2 = nmtemp;	while( (p2<tempend) && (*p2++ = *p1++)!='\0')		;	if( amatch(nmtemp,filepat) )		{		concat(dirpref,nmtemp,fullname);		if( (q=srchname(fullname)) ==0)			q = makename(copys(fullname));		if(mkchain)			{			thisdbl = ALLOC(depblock);			thisdbl->nxtdepblock = nextdbl;			thisdbl->depname = q;			nextdbl = thisdbl;			}		}	}  if(endir)	*endir = '/'; cldir(dirptr, YES); return thisdbl;} static struct dirhd *opdir(char *dirname, int stopifbad){struct dirhd *od; for(od = firstod; od; od = od->nxtdirhd)	if(equal(dirname, od->dirn) )		break; if(od == NULL)	{	++nopdir;	od = ALLOC(dirhd);	od->nxtdirhd = firstod;	firstod = od;	od->dirn = copys(dirname);	} if(od->dirfc==NULL && (od->dirfc = opendir(dirname)) == NULL && stopifbad)	{	fprintf(stderr, "Directory %s: ", dirname);	fatal("Cannot open");	} return od;}  static voidcldir(struct dirhd *dp, int used){if(nopdir >= MAXDIR)	{	closedir(dp->dirfc);	dp->dirfc = NULL;	}else if(used)	rewinddir(dp->dirfc); /* start over at the beginning  */} /* stolen from glob through find */ static intamatch(char *s, char *p){	int cc, scc, k;	int c, lc; 	scc = *s;	lc = 077777;	switch (c = *p) { 	case '[':		k = 0;		while (cc = *++p) {			switch (cc) { 			case ']':				if (k)					return amatch(++s, ++p);				else					return 0; 			case '-':				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;			}			if (scc==(lc=cc)) k++;		}		return 0; 	case '?':	caseq:		if(scc) return amatch(++s, ++p);		return 0;	case '*':		return umatch(s, ++p);	case 0:		return !scc;	}	if (c==scc) goto caseq;	return 0;} static intumatch(char *s, char *p){	if(*p==0) return 1;	while(*s)		if (amatch(s++,p)) return 1;	return 0;}#ifdef METERFILE#include <pwd.h>int meteron	= 0;	/* default: metering off */ extern void meter(char *file){time_t tvec;char *p;FILE * mout;struct passwd *pwd; if(file==0 || meteron==0) return; pwd = getpwuid(getuid()); time(&tvec); if( mout = fopen(file,"a") )	{	p = ctime(&tvec);	p[16] = '\0';	fprintf(mout, "User %s, %s\n", pwd->pw_name, p+4);	fclose(mout);	}}#endif  /* look inside archives for notation a(b)	a(b)	is file member   b   in archive a*/ static long arflen;static long arfdate;static char arfname[16];FILE *arfd;long int arpos, arlen; time_tlookarch(char *filename){char *p, *q, *send, s[15], pad;int i, nc, nsym; for(p = filename; *p!= '(' ; ++p)	; *p = '\0';if( ! openarch(filename) )	{	*p = '(';	return 0L;	}*p++ = '(';nc = 14;pad = ' '; send = s + nc;for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )	;if(p[0]==')' && p[1]!='\0')	/* forbid stuff after the paren */	{	clarch();	return 0L;	}while(q < send)	*q++ = pad;while(getarch())	{	if( !strncmp(arfname, s, nc))		{		clarch();/*TEMP fprintf(stderr, "found archive member %14s, time=%d\n", s, arfdate); */		return arfdate;		}	} clarch();return  0L;} static voidclarch(void){fclose( arfd );} static intopenarch(char *f){char magic[SARMAG];int word;struct stat buf;nameblkp p; stat(f, &buf);arlen = buf.st_size; arfd = fopen(f, "r");if(arfd == NULL)	return NO;	/* fatal1("cannot open %s", f); */ fread( (char *) &word, sizeof(word), 1, arfd); fseek(arfd, 0L, 0);fread(magic, SARMAG, 1, arfd);arpos = SARMAG;if( strncmp(magic, ARMAG, SARMAG) )	fatal1("%s is not an archive", f); if( !(p = srchname(f)) )	p = makename( copys(f) );p->isarch = YES;arflen = 0;return YES;}  static intgetarch(void){struct ar_hdr arhead; arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */if(arpos >= arlen)	return 0;fseek(arfd, arpos, 0); fread( (char *) &arhead, sizeof(arhead), 1, arfd);arpos += sizeof(arhead);arflen = atol(arhead.ar_size);arfdate = atol(arhead.ar_date);strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));return 1;} /* find the directory containing name.   read it into the hash table if it hasn't been used before or if   if might have changed since last reference*/ voiddirsrch(char *name){DIR *dirf;struct dirhd *dirp;time_t dirt, objt;int dirused, hasparen;char *dirname, *lastslash;char *fullname, *filepart, *fileend, *s;struct dirent *dptr; lastslash = NULL;hasparen = NO; for(s=name; *s; ++s)	if(*s == '/')		lastslash = s;	else if(*s=='(' || *s==')')		hasparen = YES; if(hasparen)	{	if(objt = lookarch(name))		makename(name)->modtime = objt;	return;	} if(lastslash)	{

Lines 1–500 of 561.