xref: /original-bsd/old/make/files.c (revision dbb87b25)
1*dbb87b25Sbostic static	char *sccsid = "@(#)files.c	4.22 (Berkeley) 91/02/28";
268cb908fSbostic #include <sys/types.h>
3acc982caSralph #include <fcntl.h>
4acc982caSralph 
504797f0aSwnj /* UNIX DEPENDENT PROCEDURES */
604797f0aSwnj 
704797f0aSwnj 
804797f0aSwnj /* DEFAULT RULES FOR UNIX */
904797f0aSwnj 
1004797f0aSwnj char *builtin[] =
1104797f0aSwnj 	{
1204797f0aSwnj #ifdef pwb
1304797f0aSwnj 	".SUFFIXES : .L .out .o .c .f .e .r .y .yr .ye .l .s .z .x .t .h .cl",
1404797f0aSwnj #else
15ff061234Sbostic 	".SUFFIXES : .out .o .c .F .f .e .r .y .yr .ye .l .s .cl .p .8 .7 .6 .5 .4 .3 .2 .1 .0",
1604797f0aSwnj #endif
1704797f0aSwnj 	"YACC=yacc",
1804797f0aSwnj 	"YACCR=yacc -r",
1904797f0aSwnj 	"YACCE=yacc -e",
2004797f0aSwnj 	"YFLAGS=",
2104797f0aSwnj 	"LEX=lex",
2204797f0aSwnj 	"LFLAGS=",
2304797f0aSwnj 	"CC=cc",
2468196c5fSbostic 	"CPP=cpp",
2552f48639Ssam #if defined(vax) || defined(sun) || defined(tahoe)
2604797f0aSwnj 	"AS=as",
2704797f0aSwnj #else
2804797f0aSwnj 	"AS=as -",
2904797f0aSwnj #endif
3004797f0aSwnj 	"PC=pc",
3104797f0aSwnj 	"PFLAGS=",
3204797f0aSwnj 	"CFLAGS=",
3304797f0aSwnj 	"RC=f77",
3404797f0aSwnj 	"RFLAGS=",
3564256670Swnj 	"FC=f77",
3604797f0aSwnj 	"EFLAGS=",
3704797f0aSwnj 	"FFLAGS=",
3804797f0aSwnj 	"LOADLIBES=",
39ff061234Sbostic 	"NROFF=nroff",
4004797f0aSwnj #ifdef pwb
4104797f0aSwnj 	"SCOMP=scomp",
4204797f0aSwnj 	"SCFLAGS=",
4304797f0aSwnj 	"CMDICT=cmdict",
4404797f0aSwnj 	"CMFLAGS=",
4504797f0aSwnj #endif
4604797f0aSwnj 
4704797f0aSwnj 	".c.o :",
4804797f0aSwnj 	"\t$(CC) $(CFLAGS) -c $<",
4904797f0aSwnj 
5004797f0aSwnj 	".p.o :",
5104797f0aSwnj 	"\t$(PC) $(PFLAGS) -c $<",
5204797f0aSwnj 
5304797f0aSwnj 	".cl.o :",
5404797f0aSwnj 	"\tclass -c $<",
5504797f0aSwnj 
56054eb7c1Snicklin 	".e.o .r.o .F.o .f.o :",
5704797f0aSwnj 	"\t$(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<",
5804797f0aSwnj 
5904797f0aSwnj 	".s.o :",
6004797f0aSwnj 	"\t$(AS) -o $@ $<",
6104797f0aSwnj 
6204797f0aSwnj 	".y.o :",
6304797f0aSwnj 	"\t$(YACC) $(YFLAGS) $<",
6404797f0aSwnj 	"\t$(CC) $(CFLAGS) -c y.tab.c",
6504797f0aSwnj 	"\trm y.tab.c",
6604797f0aSwnj 	"\tmv y.tab.o $@",
6704797f0aSwnj 
6804797f0aSwnj 	".yr.o:",
6904797f0aSwnj 	"\t$(YACCR) $(YFLAGS) $<",
7004797f0aSwnj 	"\t$(RC) $(RFLAGS) -c y.tab.r",
7104797f0aSwnj 	"\trm y.tab.r",
7204797f0aSwnj 	"\tmv y.tab.o $@",
7304797f0aSwnj 
7404797f0aSwnj 	".ye.o :",
7504797f0aSwnj 	"\t$(YACCE) $(YFLAGS) $<",
7604797f0aSwnj 	"\t$(EC) $(RFLAGS) -c y.tab.e",
7704797f0aSwnj 	"\trm y.tab.e",
7804797f0aSwnj 	"\tmv y.tab.o $@",
7904797f0aSwnj 
8004797f0aSwnj 	".l.o :",
8104797f0aSwnj 	"\t$(LEX) $(LFLAGS) $<",
8204797f0aSwnj 	"\t$(CC) $(CFLAGS) -c lex.yy.c",
8304797f0aSwnj 	"\trm lex.yy.c",
8404797f0aSwnj 	"\tmv lex.yy.o $@",
8504797f0aSwnj 
8604797f0aSwnj 	".y.c :",
8704797f0aSwnj 	"\t$(YACC) $(YFLAGS) $<",
8804797f0aSwnj 	"\tmv y.tab.c $@",
8904797f0aSwnj 
9004797f0aSwnj 	".l.c :",
9104797f0aSwnj 	"\t$(LEX) $(LFLAGS) $<",
9204797f0aSwnj 	"\tmv lex.yy.c $@",
9304797f0aSwnj 
9404797f0aSwnj 	".yr.r:",
9504797f0aSwnj 	"\t$(YACCR) $(YFLAGS) $<",
9604797f0aSwnj 	"\tmv y.tab.r $@",
9704797f0aSwnj 
9804797f0aSwnj 	".ye.e :",
9904797f0aSwnj 	"\t$(YACCE) $(YFLAGS) $<",
10004797f0aSwnj 	"\tmv y.tab.e $@",
10104797f0aSwnj 
10204797f0aSwnj #ifdef pwb
10304797f0aSwnj 	".o.L .c.L .t.L:",
10404797f0aSwnj 	"\t$(SCOMP) $(SCFLAGS) $<",
10504797f0aSwnj 
10604797f0aSwnj 	".t.o:",
10704797f0aSwnj 	"\t$(SCOMP) $(SCFLAGS) -c $<",
10804797f0aSwnj 
10904797f0aSwnj 	".t.c:",
11004797f0aSwnj 	"\t$(SCOMP) $(SCFLAGS) -t $<",
11104797f0aSwnj 
11204797f0aSwnj 	".h.z .t.z:",
11304797f0aSwnj 	"\t$(CMDICT) $(CMFLAGS) $<",
11404797f0aSwnj 
11504797f0aSwnj 	".h.x .t.x:",
11604797f0aSwnj 	"\t$(CMDICT) $(CMFLAGS) -c $<",
11704797f0aSwnj #endif
11804797f0aSwnj 
11904797f0aSwnj 	".s.out .c.out .o.out :",
12004797f0aSwnj 	"\t$(CC) $(CFLAGS) $< $(LOADLIBES) -o $@",
12104797f0aSwnj 
122054eb7c1Snicklin 	".f.out .F.out .r.out .e.out :",
12304797f0aSwnj 	"\t$(FC) $(EFLAGS) $(RFLAGS) $(FFLAGS) $< $(LOADLIBES) -o $@",
12404797f0aSwnj 	"\t-rm $*.o",
12504797f0aSwnj 
12604797f0aSwnj 	".y.out :",
12704797f0aSwnj 	"\t$(YACC) $(YFLAGS) $<",
12804797f0aSwnj 	"\t$(CC) $(CFLAGS) y.tab.c $(LOADLIBES) -ly -o $@",
12904797f0aSwnj 	"\trm y.tab.c",
13004797f0aSwnj 
13104797f0aSwnj 	".l.out :",
13204797f0aSwnj 	"\t$(LEX) $(LFLAGS) $<",
13304797f0aSwnj 	"\t$(CC) $(CFLAGS) lex.yy.c $(LOADLIBES) -ll -o $@",
13404797f0aSwnj 	"\trm lex.yy.c",
13504797f0aSwnj 
136ff061234Sbostic 	".8.0 :",
137ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
138ff061234Sbostic 
139ff061234Sbostic 	".7.0 :",
140ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
141ff061234Sbostic 
142ff061234Sbostic 	".6.0 :",
143ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
144ff061234Sbostic 
145ff061234Sbostic 	".5.0 :",
146ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
147ff061234Sbostic 
148ff061234Sbostic 	".4.0 :",
149ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
150ff061234Sbostic 
151ff061234Sbostic 	".3.0 :",
152ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
153ff061234Sbostic 
154ff061234Sbostic 	".2.0 :",
155ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
156ff061234Sbostic 
157ff061234Sbostic 	".1.0 :",
158ff061234Sbostic 	"\t$(NROFF) -man -h $< > $@",
159ff061234Sbostic 
16004797f0aSwnj 	0 };
16104797f0aSwnj 
16204797f0aSwnj #include "defs"
16304797f0aSwnj #include <sys/stat.h>
16424a9e40aSmckusick 
16524a9e40aSmckusick 
16624a9e40aSmckusick 
16724a9e40aSmckusick TIMETYPE
exists(pname)16824a9e40aSmckusick exists(pname)
16924a9e40aSmckusick struct nameblock *pname;
17024a9e40aSmckusick {
17104797f0aSwnj struct stat buf;
17224a9e40aSmckusick register char *s, *filename;
17304797f0aSwnj TIMETYPE lookarch();
17424a9e40aSmckusick extern char *findfl();
17524a9e40aSmckusick 
17624a9e40aSmckusick filename = pname->namep;
17704797f0aSwnj 
17804797f0aSwnj for(s = filename ; *s!='\0' && *s!='(' ; ++s)
17904797f0aSwnj 	;
18004797f0aSwnj 
18104797f0aSwnj if(*s == '(')
18204797f0aSwnj 	return(lookarch(filename));
18304797f0aSwnj 
1846f6a5a94Sroot if (stat(filename, &buf) < 0)
18524a9e40aSmckusick {
18624a9e40aSmckusick 	s = findfl(filename);
18724a9e40aSmckusick 	if(s != (char *)-1)
18824a9e40aSmckusick 	{
18924a9e40aSmckusick 		pname->alias = copys(s);
19024a9e40aSmckusick 		if(stat(pname->alias, &buf) == 0)
19124a9e40aSmckusick 			return(buf.st_mtime);
19224a9e40aSmckusick 	}
19304797f0aSwnj 	return(0);
19424a9e40aSmckusick }
19504797f0aSwnj else	return(buf.st_mtime);
19604797f0aSwnj }
19704797f0aSwnj 
19804797f0aSwnj 
prestime()19904797f0aSwnj TIMETYPE prestime()
20004797f0aSwnj {
20104797f0aSwnj TIMETYPE t;
20204797f0aSwnj time(&t);
20304797f0aSwnj return(t);
20404797f0aSwnj }
20504797f0aSwnj 
20604797f0aSwnj 
20704797f0aSwnj 
2083f84a6feSmckusick FSTATIC char nbuf[MAXNAMLEN + 1];
2093f84a6feSmckusick FSTATIC char *nbufend	= &nbuf[MAXNAMLEN];
21004797f0aSwnj 
211*dbb87b25Sbostic static int amatch();
21204797f0aSwnj 
srchdir(pat,mkchain,nextdbl)21304797f0aSwnj struct depblock *srchdir(pat, mkchain, nextdbl)
21404797f0aSwnj register char *pat; /* pattern to be matched in directory */
21504797f0aSwnj int mkchain;  /* nonzero if results to be remembered */
21604797f0aSwnj struct depblock *nextdbl;  /* final value for chain */
21704797f0aSwnj {
2183f84a6feSmckusick DIR *dirf;
21904797f0aSwnj register int i;
22004797f0aSwnj int nread, cldir;
221175799d7Sbloom char *dirname, *dirpref, *endir, *filepat, *p, temp[BUFSIZ];
222175799d7Sbloom char fullname[BUFSIZ], *p1, *p2;
22304797f0aSwnj struct nameblock *q;
22404797f0aSwnj struct depblock *thisdbl;
2253f84a6feSmckusick struct dirhdr *od;
22604797f0aSwnj struct pattern *patp;
22724a9e40aSmckusick struct varblock *cp, *varptr();
228175799d7Sbloom char *path, pth[BUFSIZ], *strcpy();
22977b8b2cfSbostic struct dirent *dptr;
23004797f0aSwnj 
23104797f0aSwnj 
23204797f0aSwnj thisdbl = 0;
23304797f0aSwnj 
23404797f0aSwnj if(mkchain == NO)
23504797f0aSwnj 	for(patp=firstpat ; patp ; patp = patp->nxtpattern)
23604797f0aSwnj 		if(! unequal(pat, patp->patval)) return(0);
23704797f0aSwnj 
23804797f0aSwnj patp = ALLOC(pattern);
23904797f0aSwnj patp->nxtpattern = firstpat;
24004797f0aSwnj firstpat = patp;
24104797f0aSwnj patp->patval = copys(pat);
24204797f0aSwnj 
24304797f0aSwnj endir = 0;
24404797f0aSwnj 
24504797f0aSwnj for(p=pat; *p!='\0'; ++p)
24604797f0aSwnj 	if(*p=='/') endir = p;
24704797f0aSwnj 
24804797f0aSwnj if(endir==0)
24904797f0aSwnj 	{
25004797f0aSwnj 	dirpref = "";
25104797f0aSwnj 	filepat = pat;
25224a9e40aSmckusick 	cp = varptr("VPATH");
25383778df3Sbostic 	if (cp->varval == NULL) path = ".";
25424a9e40aSmckusick 	else {
25524a9e40aSmckusick 	       path = pth;
25624a9e40aSmckusick 	       *path = '\0';
257f0ad4d85Sdonn 	       if (strncmp(cp->varval, ".:", 2) != 0) strcpy(pth,".:");
25824a9e40aSmckusick 	       strcat(pth, cp->varval);
25924a9e40aSmckusick 	       }
26004797f0aSwnj 	}
26104797f0aSwnj else	{
26204797f0aSwnj 	*endir = '\0';
26324a9e40aSmckusick 	path = strcpy(pth, pat);
26424a9e40aSmckusick 	dirpref = concat(pat, "/", temp);
26504797f0aSwnj 	filepat = endir+1;
26604797f0aSwnj 	}
26704797f0aSwnj 
26824a9e40aSmckusick while (*path) {			/* Loop thru each VPATH directory */
26924a9e40aSmckusick   dirname = path;
27024a9e40aSmckusick   for (; *path; path++)
27124a9e40aSmckusick     if (*path == ':') {
27224a9e40aSmckusick       *path++ = '\0';
27324a9e40aSmckusick       break;
27424a9e40aSmckusick       }
27524a9e40aSmckusick 
27604797f0aSwnj dirf = NULL;
27704797f0aSwnj cldir = NO;
27804797f0aSwnj 
27904797f0aSwnj for(od = firstod; od; od = od->nxtopendir)
28004797f0aSwnj 	if(! unequal(dirname, od->dirn) )
28104797f0aSwnj 		{
28204797f0aSwnj 		dirf = od->dirfc;
2833f84a6feSmckusick 		if (dirf != NULL)
2843f84a6feSmckusick 			rewinddir(dirf); /* start over at the beginning  */
28504797f0aSwnj 		break;
28604797f0aSwnj 		}
28704797f0aSwnj 
28804797f0aSwnj if(dirf == NULL)
28904797f0aSwnj 	{
2903f84a6feSmckusick 	dirf = opendir(dirname);
29104797f0aSwnj 	if(nopdir >= MAXDIR)
29204797f0aSwnj 		cldir = YES;
29304797f0aSwnj 	else	{
29404797f0aSwnj 		++nopdir;
2953f84a6feSmckusick 		od = ALLOC(dirhdr);
29604797f0aSwnj 		od->nxtopendir = firstod;
29704797f0aSwnj 		firstod = od;
29804797f0aSwnj 		od->dirfc = dirf;
29904797f0aSwnj 		od->dirn = copys(dirname);
3001521c392Sbostic 		fcntl(dirfd(dirf), F_SETFD, 1);
30104797f0aSwnj 		}
30204797f0aSwnj 	}
30304797f0aSwnj 
30404797f0aSwnj if(dirf == NULL)
30504797f0aSwnj 	{
30604797f0aSwnj 	fprintf(stderr, "Directory %s: ", dirname);
30704797f0aSwnj 	fatal("Cannot open");
30804797f0aSwnj 	}
30904797f0aSwnj 
3103f84a6feSmckusick else for (dptr = readdir(dirf); dptr != NULL; dptr = readdir(dirf))
31104797f0aSwnj 	{
3123f84a6feSmckusick 	p1 = dptr->d_name;
3133f84a6feSmckusick 	p2 = nbuf;
3143f84a6feSmckusick 	while( (p2<nbufend) && (*p2++ = *p1++)!='\0' )
3153f84a6feSmckusick 		/* void */;
3163f84a6feSmckusick 	if( amatch(nbuf,filepat) )
31704797f0aSwnj 		{
3183f84a6feSmckusick 		concat(dirpref,nbuf,fullname);
31904797f0aSwnj 		if( (q=srchname(fullname)) ==0)
32004797f0aSwnj 			q = makename(copys(fullname));
32104797f0aSwnj 		if(mkchain)
32204797f0aSwnj 			{
32304797f0aSwnj 			thisdbl = ALLOC(depblock);
32404797f0aSwnj 			thisdbl->nxtdepblock = nextdbl;
32504797f0aSwnj 			thisdbl->depname = q;
32604797f0aSwnj 			nextdbl = thisdbl;
32704797f0aSwnj 			}
32804797f0aSwnj 		}
32904797f0aSwnj 	}
33004797f0aSwnj 
33104797f0aSwnj if(endir != 0)  *endir = '/';
33204797f0aSwnj 
3333f84a6feSmckusick if(cldir) {
3343f84a6feSmckusick 	closedir(dirf);
3353f84a6feSmckusick 	dirf = NULL;
3363f84a6feSmckusick }
33724a9e40aSmckusick } /* End of VPATH loop */
33804797f0aSwnj return(thisdbl);
33904797f0aSwnj }
34004797f0aSwnj 
34104797f0aSwnj /* stolen from glob through find */
34204797f0aSwnj 
amatch(s,p)34304797f0aSwnj static amatch(s, p)
34404797f0aSwnj char *s, *p;
34504797f0aSwnj {
34604797f0aSwnj 	register int cc, scc, k;
34704797f0aSwnj 	int c, lc;
348*dbb87b25Sbostic 	static int umatch();
34904797f0aSwnj 
35004797f0aSwnj 	scc = *s;
35104797f0aSwnj 	lc = 077777;
35204797f0aSwnj 	switch (c = *p) {
35304797f0aSwnj 
35404797f0aSwnj 	case '[':
35504797f0aSwnj 		k = 0;
35604797f0aSwnj 		while (cc = *++p) {
35704797f0aSwnj 			switch (cc) {
35804797f0aSwnj 
35904797f0aSwnj 			case ']':
36004797f0aSwnj 				if (k)
36104797f0aSwnj 					return(amatch(++s, ++p));
36204797f0aSwnj 				else
36304797f0aSwnj 					return(0);
36404797f0aSwnj 
36504797f0aSwnj 			case '-':
36604797f0aSwnj 				k |= (lc <= scc)  & (scc <= (cc=p[1]) ) ;
36704797f0aSwnj 			}
36804797f0aSwnj 			if (scc==(lc=cc)) k++;
36904797f0aSwnj 		}
37004797f0aSwnj 		return(0);
37104797f0aSwnj 
37204797f0aSwnj 	case '?':
37304797f0aSwnj 	caseq:
37404797f0aSwnj 		if(scc) return(amatch(++s, ++p));
37504797f0aSwnj 		return(0);
37604797f0aSwnj 	case '*':
37704797f0aSwnj 		return(umatch(s, ++p));
37804797f0aSwnj 	case 0:
37904797f0aSwnj 		return(!scc);
38004797f0aSwnj 	}
38104797f0aSwnj 	if (c==scc) goto caseq;
38204797f0aSwnj 	return(0);
38304797f0aSwnj }
38404797f0aSwnj 
umatch(s,p)38504797f0aSwnj static umatch(s, p)
38604797f0aSwnj char *s, *p;
38704797f0aSwnj {
38804797f0aSwnj 	if(*p==0) return(1);
38904797f0aSwnj 	while(*s)
39004797f0aSwnj 		if (amatch(s++,p)) return(1);
39104797f0aSwnj 	return(0);
39204797f0aSwnj }
39304797f0aSwnj 
39404797f0aSwnj #ifdef METERFILE
39504797f0aSwnj #include <pwd.h>
39604797f0aSwnj int meteron	= 0;	/* default: metering off */
39704797f0aSwnj 
meter(file)39804797f0aSwnj meter(file)
39904797f0aSwnj char *file;
40004797f0aSwnj {
40104797f0aSwnj TIMETYPE tvec;
40204797f0aSwnj char *p, *ctime();
40304797f0aSwnj FILE * mout;
40404797f0aSwnj struct passwd *pwd, *getpwuid();
40504797f0aSwnj 
40604797f0aSwnj if(file==0 || meteron==0) return;
40704797f0aSwnj 
40804797f0aSwnj pwd = getpwuid(getuid());
40904797f0aSwnj 
41004797f0aSwnj time(&tvec);
41104797f0aSwnj 
41204797f0aSwnj if( (mout=fopen(file,"a")) != NULL )
41304797f0aSwnj 	{
41404797f0aSwnj 	p = ctime(&tvec);
41504797f0aSwnj 	p[16] = '\0';
41604797f0aSwnj 	fprintf(mout,"User %s, %s\n",pwd->pw_name,p+4);
41704797f0aSwnj 	fclose(mout);
41804797f0aSwnj 	}
41904797f0aSwnj }
42004797f0aSwnj #endif
42104797f0aSwnj 
42204797f0aSwnj 
42304797f0aSwnj /* look inside archives for notations a(b) and a((b))
42404797f0aSwnj 	a(b)	is file member   b   in archive a
42504797f0aSwnj 	a((b))	is entry point  _b  in object archive a
42604797f0aSwnj */
42704797f0aSwnj 
42804797f0aSwnj #ifdef ASCARCH
42904797f0aSwnj #	include <ar.h>
43004797f0aSwnj #else
43104797f0aSwnj #	include <ar.h>
43204797f0aSwnj #endif
43304797f0aSwnj #include <a.out.h>
43404797f0aSwnj 
43504797f0aSwnj static long arflen;
43604797f0aSwnj static long arfdate;
43704797f0aSwnj static char arfname[16];
43804797f0aSwnj FILE *arfd;
43904797f0aSwnj long int arpos, arlen;
44004797f0aSwnj 
44104797f0aSwnj static struct exec objhead;
44204797f0aSwnj 
44304797f0aSwnj static struct nlist objentry;
44404797f0aSwnj 
44504797f0aSwnj 
lookarch(filename)44604797f0aSwnj TIMETYPE lookarch(filename)
44704797f0aSwnj char *filename;
44804797f0aSwnj {
4493f84a6feSmckusick char *p, *q, *send, s[MAXNAMLEN + 1];
45004797f0aSwnj int i, nc, nsym, objarch;
45104797f0aSwnj 
45204797f0aSwnj for(p = filename; *p!= '(' ; ++p)
45304797f0aSwnj 	;
45404797f0aSwnj *p = '\0';
45504797f0aSwnj openarch(filename);
45604797f0aSwnj *p++ = '(';
45704797f0aSwnj 
45804797f0aSwnj if(*p == '(')
45904797f0aSwnj 	{
46004797f0aSwnj 	objarch = YES;
46104797f0aSwnj 	nc = 8;
46204797f0aSwnj 	++p;
46304797f0aSwnj 	}
46404797f0aSwnj else
46504797f0aSwnj 	{
46604797f0aSwnj 	objarch = NO;
4673f84a6feSmckusick 	nc = MAXNAMLEN;
46804797f0aSwnj 	}
46904797f0aSwnj send = s + nc;
47004797f0aSwnj 
47104797f0aSwnj for( q = s ; q<send && *p!='\0' && *p!=')' ; *q++ = *p++ )
47204797f0aSwnj 	;
47304797f0aSwnj while(q < send)
47404797f0aSwnj 	*q++ = '\0';
47504797f0aSwnj while(getarch())
47604797f0aSwnj 	{
47704797f0aSwnj 	if(objarch)
47804797f0aSwnj 		{
47904797f0aSwnj 		getobj();
48004797f0aSwnj 		nsym = objhead.a_syms / sizeof(objentry);
48104797f0aSwnj 		for(i = 0; i<nsym ; ++i)
48204797f0aSwnj 			{
48304797f0aSwnj 			fread( (char *) &objentry, sizeof(objentry),1,arfd);
48404797f0aSwnj 			if( (objentry.n_type & N_EXT)
48504797f0aSwnj 			   && ((objentry.n_type & ~N_EXT) || objentry.n_value)
48604797f0aSwnj 			   && eqstr(objentry.n_un.n_name,s,nc))
48704797f0aSwnj 				{
48804797f0aSwnj 				clarch();
48904797f0aSwnj 				return(arfdate);
49004797f0aSwnj 				}
49104797f0aSwnj 			}
49204797f0aSwnj 		}
49304797f0aSwnj 
49404797f0aSwnj 	else if( eqstr(arfname, s, nc))
49504797f0aSwnj 		{
49604797f0aSwnj 		clarch();
49704797f0aSwnj 		return(arfdate);
49804797f0aSwnj 		}
49904797f0aSwnj 	}
50004797f0aSwnj 
50104797f0aSwnj clarch();
50204797f0aSwnj return( 0L);
50304797f0aSwnj }
50404797f0aSwnj 
50504797f0aSwnj 
clarch()50604797f0aSwnj clarch()
50704797f0aSwnj {
50804797f0aSwnj fclose( arfd );
50904797f0aSwnj }
51004797f0aSwnj 
51104797f0aSwnj 
openarch(f)51204797f0aSwnj openarch(f)
51304797f0aSwnj register char *f;
51404797f0aSwnj {
51504797f0aSwnj #ifdef ASCARCH
51604797f0aSwnj char magic[SARMAG];
51704797f0aSwnj #endif
51804797f0aSwnj int word;
51904797f0aSwnj struct stat buf;
52004797f0aSwnj 
52104797f0aSwnj stat(f, &buf);
52204797f0aSwnj arlen = buf.st_size;
52304797f0aSwnj 
52404797f0aSwnj arfd = fopen(f, "r");
52504797f0aSwnj if(arfd == NULL)
52604797f0aSwnj 	fatal1("cannot open %s", f);
52704797f0aSwnj 
52804797f0aSwnj 	fread( (char *) &word, sizeof(word), 1, arfd);
52904797f0aSwnj #ifdef ASCARCH
53004797f0aSwnj 	fseek(arfd, 0L, 0);
53104797f0aSwnj 	fread(magic, SARMAG, 1, arfd);
53204797f0aSwnj 	arpos = SARMAG;
53304797f0aSwnj 	if( ! eqstr(magic, ARMAG, SARMAG) )
53404797f0aSwnj #else
53504797f0aSwnj 	arpos = sizeof(word);
53604797f0aSwnj 	if(word != ARMAG)
53704797f0aSwnj #endif
53804797f0aSwnj 		fatal1("%s is not an archive", f);
53904797f0aSwnj 
54004797f0aSwnj arflen = 0;
54104797f0aSwnj }
54204797f0aSwnj 
54304797f0aSwnj 
54404797f0aSwnj 
getarch()54504797f0aSwnj getarch()
54604797f0aSwnj {
54704797f0aSwnj 	struct ar_hdr arhead;
54804797f0aSwnj 	long atol();
54904797f0aSwnj 
55004797f0aSwnj arpos += (arflen + 1) & ~1L;	/* round archived file length up to even */
55104797f0aSwnj if(arpos >= arlen)
55204797f0aSwnj 	return(0);
55304797f0aSwnj fseek(arfd, arpos, 0);
55404797f0aSwnj 
55504797f0aSwnj 	fread( (char *) &arhead, sizeof(arhead), 1, arfd);
55604797f0aSwnj 	arpos += sizeof(arhead);
55704797f0aSwnj #ifdef ASCARCH
55804797f0aSwnj 	arflen = atol(arhead.ar_size);
55904797f0aSwnj 	arfdate = atol(arhead.ar_date);
56004797f0aSwnj #else
56104797f0aSwnj 	arflen = arhead.ar_size;
56204797f0aSwnj 	arfdate = arhead.ar_date;
56304797f0aSwnj #endif
56404797f0aSwnj 	strncpy(arfname, arhead.ar_name, sizeof(arhead.ar_name));
56504797f0aSwnj return(1);
56604797f0aSwnj }
56704797f0aSwnj 
56804797f0aSwnj 
getobj()56904797f0aSwnj getobj()
57004797f0aSwnj {
57104797f0aSwnj long int skip;
57204797f0aSwnj 
57304797f0aSwnj fread( (char *) &objhead, sizeof(objhead), 1, arfd);
57404797f0aSwnj if (N_BADMAG(objhead))
57504797f0aSwnj 	fatal1("%s is not an object module", arfname);
57604797f0aSwnj skip = objhead.a_text + objhead.a_data;
577fe87a756Sbloom #ifndef pdp11
57804797f0aSwnj skip += objhead.a_trsize + objhead.a_drsize;
57904797f0aSwnj #else
58004797f0aSwnj if(! objhead.a_flag )
58104797f0aSwnj 	skip *= 2;
58204797f0aSwnj #endif
58304797f0aSwnj fseek(arfd, skip, 1);
58404797f0aSwnj }
58504797f0aSwnj 
58604797f0aSwnj 
eqstr(a,b,n)58704797f0aSwnj eqstr(a,b,n)
58804797f0aSwnj register char *a, *b;
58904797f0aSwnj int n;
59004797f0aSwnj {
59104797f0aSwnj register int i;
59204797f0aSwnj for(i = 0 ; i < n ; ++i)
59304797f0aSwnj 	if(*a++ != *b++)
59404797f0aSwnj 		return(NO);
59504797f0aSwnj return(YES);
59604797f0aSwnj }
59724a9e40aSmckusick 
59824a9e40aSmckusick 
59924a9e40aSmckusick /*
60024a9e40aSmckusick  *	findfl(name)	(like execvp, but does path search and finds files)
60124a9e40aSmckusick  */
60224a9e40aSmckusick static char fname[128];
60324a9e40aSmckusick 
60424a9e40aSmckusick char *execat();
60524a9e40aSmckusick 
findfl(name)60624a9e40aSmckusick char *findfl(name)
60724a9e40aSmckusick register char *name;
60824a9e40aSmckusick {
60924a9e40aSmckusick 	register char *p;
61024a9e40aSmckusick 	register struct varblock *cp;
61124a9e40aSmckusick 	struct stat buf;
6127906b1edSbostic 	struct varblock *varptr();
61324a9e40aSmckusick 
61424a9e40aSmckusick 	for (p = name; *p; p++)
61524a9e40aSmckusick 		if(*p == '/') return(name);
61624a9e40aSmckusick 
61724a9e40aSmckusick 	cp = varptr("VPATH");
61824a9e40aSmckusick 	if(cp->varval == NULL || *cp->varval == 0)
61924a9e40aSmckusick 		p = ":";
62024a9e40aSmckusick 	else
62124a9e40aSmckusick 		p = cp->varval;
62224a9e40aSmckusick 
62324a9e40aSmckusick 	do
62424a9e40aSmckusick 	{
62524a9e40aSmckusick 		p = execat(p, name, fname);
62624a9e40aSmckusick 		if(stat(fname,&buf) >= 0)
62724a9e40aSmckusick 			return(fname);
62824a9e40aSmckusick 	} while (p);
62924a9e40aSmckusick 	return((char *)-1);
63024a9e40aSmckusick }
63124a9e40aSmckusick 
execat(s1,s2,si)63224a9e40aSmckusick char *execat(s1, s2, si)
63324a9e40aSmckusick register char *s1, *s2;
63424a9e40aSmckusick char *si;
63524a9e40aSmckusick {
63624a9e40aSmckusick 	register char *s;
63724a9e40aSmckusick 
63824a9e40aSmckusick 	s = si;
63924a9e40aSmckusick 	while (*s1 && *s1 != ':' && *s1 != '-')
64024a9e40aSmckusick 		*s++ = *s1++;
64124a9e40aSmckusick 	if (si != s)
64224a9e40aSmckusick 		*s++ = '/';
64324a9e40aSmckusick 	while (*s2)
64424a9e40aSmckusick 		*s++ = *s2++;
64524a9e40aSmckusick 	*s = '\0';
64624a9e40aSmckusick 	return(*s1? ++s1: 0);
64724a9e40aSmckusick }
64824a9e40aSmckusick 
64924a9e40aSmckusick 
65024a9e40aSmckusick /* copy s to d, changing file names to file aliases */
fixname(s,d)65124a9e40aSmckusick fixname(s, d)
65224a9e40aSmckusick char *s, *d;
65324a9e40aSmckusick {
65424a9e40aSmckusick 	register char *r, *q;
65524a9e40aSmckusick 	struct nameblock *pn;
656175799d7Sbloom 	char name[BUFSIZ];
65724a9e40aSmckusick 
65824a9e40aSmckusick 	while (*s) {
65924a9e40aSmckusick 		if (isspace(*s)) *d++ = *s++;
66024a9e40aSmckusick 		else {
66124a9e40aSmckusick 			r = name;
66224a9e40aSmckusick 			while (*s) {
66324a9e40aSmckusick 				if (isspace(*s)) break;
66424a9e40aSmckusick 				*r++ = *s++;
66524a9e40aSmckusick 				}
66624a9e40aSmckusick 			*r = '\0';
66724a9e40aSmckusick 
66824a9e40aSmckusick 			if (((pn = srchname(name)) != 0) && (pn->alias))
66924a9e40aSmckusick 				q = pn->alias;
67024a9e40aSmckusick 			else q = name;
67124a9e40aSmckusick 
67224a9e40aSmckusick 			while (*q) *d++ = *q++;
67324a9e40aSmckusick 			}
67424a9e40aSmckusick 		}
67524a9e40aSmckusick 	*d = '\0';
67624a9e40aSmckusick }
677