pdp11v/usr/src/cmd/make/files.c

Compare this file to the similar file:
Show the results in this format:

/*	@(#)/usr/src/cmd/make/files.c	3.4	*/

#include "defs"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include <pwd.h>
#include <ar.h>
#include <a.out.h>
/* UNIX DEPENDENT PROCEDURES */


char archmem[16];
char archname[64];		/* name of archive library */


TIMETYPE exists(pname)
NAMEBLOCK pname;
{
	register CHARSTAR s;
	struct stat buf;
	TIMETYPE lookarch();
	CHARSTAR filename;

	filename = pname->namep;

	if(any(filename, LPAREN))
		return(lookarch(filename));

	if(stat(filename,&buf) < 0) 
	{
		s = findfl(filename);
		if(s != (CHARSTAR )-1)
		{
			pname->alias = copys(s);
			if(stat(pname->alias, &buf) == 0)
				return(buf.st_mtime);
		}
		return(0);
	}
	else
		return(buf.st_mtime);
}


TIMETYPE prestime()
{
	TIMETYPE t;
	time(&t);
	return(t);
}



FSTATIC char n15[15];
FSTATIC CHARSTAR n15end = &n15[14];



DEPBLOCK srchdir(pat, mkchain, nextdbl)
register CHARSTAR pat;		/* pattern to be matched in directory */
int mkchain;			/* nonzero if results to be remembered */
DEPBLOCK nextdbl;		/* final value for chain */
{
	FILE * dirf;
	int i, nread;
	CHARSTAR dirname, dirpref, endir, filepat, p;
	char temp[100];
	char fullname[100];
	CHARSTAR p1, p2;
	NAMEBLOCK q;
	DEPBLOCK thisdbl;
	OPENDIR od;
	int dirofl = 0;
	static opendirs = 0;
	PATTERN patp;

	struct direct entry[32];


	thisdbl = 0;

	if(mkchain == NO)
		for(patp=firstpat ; patp!=0 ; patp = patp->nextpattern)
			if(equal(pat,patp->patval))
				return(0);

	patp = ALLOC(pattern);
	patp->nextpattern = firstpat;
	firstpat = patp;
	patp->patval = copys(pat);

	endir = 0;

	for(p=pat; *p!=CNULL; ++p)
		if(*p==SLASH)
			endir = p;

	if(endir==0)
	{
		dirname = ".";
		dirpref = "";
		filepat = pat;
	}
	else
	{
		*endir = CNULL;
		dirpref = concat(pat, "/", temp);
		filepat = endir+1;
		dirname = temp;
	}

	dirf = NULL;

	for(od=firstod ; od!=0; od = od->nextopendir)
		if(equal(dirname, od->dirn))
		{
			dirf = od->dirfc;
			fseek(dirf,0L,0); /* start over at the beginning  */
			break;
		}

	if(dirf == NULL)
	{
		dirf = fopen(dirname, "r");
		if(++opendirs < MAXODIR)
		{
			od = ALLOC(opendir);
			od->nextopendir = firstod;
			firstod = od;
			od->dirfc = dirf;
			od->dirn = copys(dirname);
		}
		else
			dirofl = 1;
	}

	if(dirf == NULL)
	{
		fprintf(stderr, "Directory %s: ", dirname);
		fatal("Cannot open");
	}

	else	do
		{
			nread = fread(entry,sizeof(entry[0]),32,dirf) ;
			for(i=0; i<nread; ++i)
				if(entry[i].d_ino!= 0)
				{
					p1 = entry[i].d_name;
					p2 = n15;
					while( (p2<n15end) &&
					  (*p2++ = *p1++)!=CNULL );
					if( amatch(n15,filepat) )
					{
						concat(dirpref,n15,fullname);
						if( (q=srchname(fullname)) ==0)
							q = makename(copys(fullname));
						if(mkchain)
						{
							thisdbl = ALLOC(depblock);
							thisdbl->nextdep = nextdbl;
							thisdbl->depname = q;
							nextdbl = thisdbl;
						}
					}
				}
		} while(nread==32);

	if(endir != 0)
		*endir = SLASH;
	if(dirofl)
		fclose(dirf);

	return(thisdbl);
}

/* stolen from glob through find */

amatch(s, p)
CHARSTAR s, p;
{
	register int cc, scc, k;
	int c, lc;

	scc = *s;
	lc = 077777;
	switch (c = *p)
	{

	case LSQUAR:
		k = 0;
		while (cc = *++p)
		{
			switch (cc)
			{

			case RSQUAR:
				if (k)
					return(amatch(++s, ++p));
				else
					return(0);

			case MINUS:
				k |= lc <= scc & scc <= (cc=p[1]);
			}
			if(scc==(lc=cc))
				k++;
		}
		return(0);

	case QUESTN:
	caseq:
		if(scc)
			return(amatch(++s, ++p));
		return(0);
	case STAR:
		return(umatch(s, ++p));
	case 0:
		return(!scc);
	}
	if(c==scc)
		goto caseq;
	return(0);
}

umatch(s, p)
register CHARSTAR s, p;
{
	if(*p==0)
		return(1);
	while(*s)
		if(amatch(s++,p))
			return(1);
	return(0);
}

#ifdef METERFILE
int meteron 0;	/* default: metering off */

meter(file)
CHARSTAR file;
{
	TIMETYPE tvec;
	CHARSTAR p, ctime();
	FILE * mout;
	struct passwd *pwd, *getpwuid();

	if(file==0 || meteron==0)
		return;

	pwd = getpwuid(getuid());

	time(&tvec);

	if( (mout=fopen(file,"a")) != NULL )
	{
		p = ctime(&tvec);
		p[16] = CNULL;
		fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
		fclose(mout);
	}
}
#endif


/* look inside archives for notations a(b) and a((b))
	a(b)	is file member   b   in archive a
	a((b))	is entry point  _b  in object archive a
*/

static struct ar_hdr arhead;
FILE *arfd;
long int arpos, arlen;

static struct exec objhead;

static struct nlist objentry;


TIMETYPE lookarch(filename)
register CHARSTAR filename;
{
	register int i;
	CHARSTAR p, q, send;
	char s[15];
	int nc, nsym, objarch;

	for(p = filename; *p!= LPAREN ; ++p);
	q = p++;

	if(*p == LPAREN)
	{
		objarch = YES;
		nc = 8;
		++p;
	}
	else
	{
		objarch = NO;
		nc = 14;
		for(i = 0; i < 14; i++)
		{
			if(p[i] == RPAREN)
			{
				i--;
				break;
			}
			archmem[i] = p[i];
		}
		archmem[++i] = 0;
		if(archmem[0] == CNULL)
			fatal1("Null archive member name `%s'", filename);
	}
	*q = CNULL;
	copstr(archname, filename);
	if(archname[0] == CNULL)
		fatal1("Null archive name `%s'", archmem);
	i = openarch(filename);
	*q = LPAREN;
	if(i == -1)
		return(0);
	send = s + nc;

	for( q = s ; q<send && *p!=CNULL && *p!=RPAREN ; *q++ = *p++ );

	while(q < send)
		*q++ = CNULL;
	while(getarch())
	{
		if(objarch)
		{
			getobj();
			nsym = objhead.a_syms / sizeof(objentry);
			for(i = 0; i<nsym ; ++i)
			{
				fread(&objentry, sizeof(objentry),1,arfd);
				if( (objentry.n_type & N_EXT)
				   && eqstr(objentry.n_name,s,nc))
				{
					for(i = 0; i < 14; i++)
						archmem[i] = arhead.ar_name[i];
					archmem[++i] = 0;
	out:
					clarch();
					return(arhead.ar_date);
				}
			}
		}

		else if( eqstr(arhead.ar_name, s, nc))
			goto out;
	}

	clarch();
	return( 0L);
}


clarch()
{
	fclose( arfd );
}


openarch(f)
register CHARSTAR f;
{
	int word = 0;
	struct stat buf;

	if(stat(f, &buf) == -1)
		return(-1);
	arlen = buf.st_size;

	arfd = fopen(f, "r");
	if(arfd == NULL)
		return(-1);
	fread(&word, sizeof(word), 1, arfd);
	if(word != ARMAG)
		fatal1("%s is not an archive", f);
/*
 *	trick getarch() into jumping to the first archive member.
 */
	arpos = sizeof(word);
	arhead.ar_size = -(int)sizeof(arhead);
	return(0);
}



getarch()
{
	arpos += sizeof(arhead);
	arpos += (arhead.ar_size + 1 ) & ~1L;
	if(arpos >= arlen)
		return(0);
	fseek(arfd, arpos, 0);
	fread(&arhead, sizeof(arhead), 1, arfd);
	return(1);
}


getobj()
{
	long int skip;

	fread(&objhead, sizeof(objhead), 1, arfd);
	if( objhead.a_magic != A_MAGIC1 &&
	    objhead.a_magic != A_MAGIC2 &&
	    objhead.a_magic != A_MAGIC3 )
			fatal1("%s is not an object module", arhead.ar_name);
	skip = objhead.a_text + objhead.a_data;
#if vax || u370
	skip += objhead.a_trsize + objhead.a_drsize;
#else
	if(! objhead.a_flag )
		skip *= 2;
#endif
	fseek(arfd, skip, 1);
}


eqstr(a,b,n)
register CHARSTAR a, b;
register int n;
{
	register int i;
	for(i = 0 ; i < n ; ++i)
		if(*a++ != *b++)
			return(NO);
	return(YES);
}
/*
 *	Used when unlinking files. If file cannot be stat'ed or it is
 *	a directory, then do not remove it.
 */
isdir(p)
char *p;
{
	struct stat statbuf;

	if(stat(p, &statbuf) == -1)
		return(1);		/* no stat, no remove */
	if((statbuf.st_mode&S_IFMT) == S_IFDIR)
		return(1);
	return(0);
}