1238438Sdteske/*-
2238438Sdteske * Copyright (c) 1988, 1989, 1990, 1993
3238438Sdteske *	The Regents of the University of California.  All rights reserved.
4238438Sdteske * Copyright (c) 1989 by Berkeley Softworks
5238438Sdteske * All rights reserved.
6272230Sdteske *
7238438Sdteske * This code is derived from software contributed to Berkeley by
8238438Sdteske * Adam de Boor.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)arch.c	8.2 (Berkeley) 1/2/94
39 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: releng/10.3/usr.bin/make/arch.c 228992 2011-12-30 11:02:40Z uqs $");
43
44/*-
45 * arch.c --
46 *	Functions to manipulate libraries, archives and their members.
47 *
48 *	Once again, cacheing/hashing comes into play in the manipulation
49 * of archives. The first time an archive is referenced, all of its members'
50 * headers are read and hashed and the archive closed again. All hashed
51 * archives are kept on a list which is searched each time an archive member
52 * is referenced.
53 *
54 * The interface to this module is:
55 *	Arch_ParseArchive	Given an archive specification, return a list
56 *				of GNode's, one for each member in the spec.
57 *				FALSE is returned if the specification is
58 *				invalid for some reason.
59 *
60 *	Arch_Touch		Alter the modification time of the archive
61 *				member described by the given node to be
62 *				the current time.
63 *
64 *	Arch_TouchLib		Update the modification time of the library
65 *				described by the given node. This is special
66 *				because it also updates the modification time
67 *				of the library's table of contents.
68 *
69 *	Arch_MTime		Find the modification time of a member of
70 *				an archive *in the archive*. The time is also
71 *				placed in the member's GNode. Returns the
72 *				modification time.
73 *
74 *	Arch_MemTime		Find the modification time of a member of
75 *				an archive. Called when the member doesn't
76 *				already exist. Looks in the archive for the
77 *				modification time. Returns the modification
78 *				time.
79 *
80 *	Arch_FindLib		Search for a library along a path. The
81 *				library name in the GNode should be in
82 *				-l<name> format.
83 *
84 *	Arch_LibOODate		Special function to decide if a library node
85 *				is out-of-date.
86 *
87 *	Arch_Init		Initialize this module.
88 */
89
90#include <sys/param.h>
91#include <sys/queue.h>
92#include <sys/types.h>
93#include <ar.h>
94#include <ctype.h>
95#include <errno.h>
96#include <inttypes.h>
97#include <limits.h>
98#include <regex.h>
99#include <stdlib.h>
100#include <stdio.h>
101#include <string.h>
102#include <utime.h>
103
104#include "arch.h"
105#include "buf.h"
106#include "config.h"
107#include "dir.h"
108#include "globals.h"
109#include "GNode.h"
110#include "hash.h"
111#include "make.h"
112#include "parse.h"
113#include "targ.h"
114#include "util.h"
115#include "var.h"
116
117typedef struct Arch {
118	char		*name;		/* Name of archive */
119
120	/*
121	 * All the members of the archive described
122	 * by <name, struct ar_hdr *> key/value pairs
123	 */
124	Hash_Table	members;
125
126	TAILQ_ENTRY(Arch) link;		/* link all cached archives */
127} Arch;
128
129/* Lst of archives we've already examined */
130static TAILQ_HEAD(, Arch) archives = TAILQ_HEAD_INITIALIZER(archives);
131
132
133/* size of the name field in the archive member header */
134#define	AR_NAMSIZ	sizeof(((struct ar_hdr *)0)->ar_name)
135
136/*
137 * This structure is used while reading/writing an archive
138 */
139struct arfile {
140	FILE		*fp;		/* archive file */
141	char		*fname;		/* name of the file */
142	struct ar_hdr	hdr;		/* current header */
143	char		sname[AR_NAMSIZ + 1]; /* short name */
144	char		*member;	/* (long) member name */
145	size_t		mlen;		/* size of the above */
146	char		*nametab;	/* name table */
147	size_t		nametablen;	/* size of the table */
148	int64_t		time;		/* from ar_date */
149	uint64_t	size;		/* from ar_size */
150	off_t		pos;		/* header pos of current entry */
151};
152
153/*
154 * Name of the symbol table. The original BSD used "__.SYMDEF". Rumours go
155 * that this name may have a slash appended sometimes. Actually FreeBSD
156 * uses "/" which probably came from SVR4.
157 */
158#define	SVR4_RANLIBMAG	"/"
159#define	BSD_RANLIBMAG	"__.SYMDEF"
160
161/*
162 * Name of the filename table. The 4.4BSD ar format did not use this, but
163 * puts long filenames directly between the member header and the object
164 * file.
165 */
166#define	SVR4_NAMEMAG	"//"
167#define	BSD_NAMEMAG	"ARFILENAMES/"
168
169/*
170 * 44BSD long filename key. Use a local define here instead of relying
171 * on ar.h because we want this to continue working even when the
172 * definition is removed from ar.h.
173 */
174#define	BSD_EXT1	"#1/"
175#define	BSD_EXT1LEN	3
176
177/* if this is TRUE make archive errors fatal */
178Boolean arch_fatal = TRUE;
179
180/**
181 * ArchError
182 *	An error happened while handling an archive. BSDmake traditionally
183 *	ignored these errors. Now this is dependent on the global arch_fatal
184 *	which, if true, makes these errors fatal and, if false, just emits an
185 *	error message.
186 */
187#define	ArchError(ARGS) do {					\
188	if (arch_fatal)						\
189		Fatal ARGS;					\
190	else							\
191		Error ARGS;					\
192    } while (0)
193
194/*-
195 *-----------------------------------------------------------------------
196 * Arch_ParseArchive --
197 *	Parse the archive specification in the given line and find/create
198 *	the nodes for the specified archive members, placing their nodes
199 *	on the given list, given the pointer to the start of the
200 *	specification, a Lst on which to place the nodes, and a context
201 *	in which to expand variables.
202 *
203 * Results:
204 *	TRUE if it was a valid specification. The linePtr is updated
205 *	to point to the first non-space after the archive spec. The
206 *	nodes for the members are placed on the given list.
207 *
208 * Side Effects:
209 *	Some nodes may be created. The given list is extended.
210 *
211 *-----------------------------------------------------------------------
212 */
213Boolean
214Arch_ParseArchive(char **linePtr, Lst *nodeLst, GNode *ctxt)
215{
216	char	*cp;		/* Pointer into line */
217	GNode	*gn;		/* New node */
218	char	*libName;	/* Library-part of specification */
219	char	*memName;	/* Member-part of specification */
220	char	*nameBuf;	/* temporary place for node name */
221	char	saveChar;	/* Ending delimiter of member-name */
222	Boolean	subLibName;	/* TRUE if libName should have/had
223				 * variable substitution performed on it */
224
225	libName = *linePtr;
226
227	subLibName = FALSE;
228
229	for (cp = libName; *cp != '(' && *cp != '\0'; cp++) {
230		if (*cp == '$') {
231			/*
232			 * Variable spec, so call the Var module to parse the
233			 * puppy so we can safely advance beyond it...
234			 */
235			size_t	length = 0;
236			Boolean	freeIt;
237			char	*result;
238
239			result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
240			if (result == var_Error) {
241				return (FALSE);
242			}
243			subLibName = TRUE;
244
245			if (freeIt) {
246				free(result);
247			}
248			cp += length - 1;
249		}
250	}
251
252	*cp++ = '\0';
253	if (subLibName) {
254		libName = Buf_Peel(Var_Subst(libName, ctxt, TRUE));
255	}
256
257	for (;;) {
258		/*
259		 * First skip to the start of the member's name, mark that
260		 * place and skip to the end of it (either white-space or
261		 * a close paren).
262		 */
263
264		/*
265		 * TRUE if need to substitute in memName
266		 */
267		Boolean	doSubst = FALSE;
268
269		while (*cp != '\0' && *cp != ')' &&
270		    isspace((unsigned char)*cp)) {
271			cp++;
272		}
273
274		memName = cp;
275		while (*cp != '\0' && *cp != ')' &&
276		    !isspace((unsigned char)*cp)) {
277			if (*cp == '$') {
278				/*
279				 * Variable spec, so call the Var module to
280				 * parse the puppy so we can safely advance
281				 * beyond it...
282				 */
283				size_t	length = 0;
284				Boolean	freeIt;
285				char	*result;
286
287				result = Var_Parse(cp, ctxt, TRUE,
288				    &length, &freeIt);
289				if (result == var_Error) {
290					return (FALSE);
291				}
292				doSubst = TRUE;
293
294				if (freeIt) {
295					free(result);
296				}
297				cp += length;
298			} else {
299				cp++;
300			}
301		}
302
303		/*
304		 * If the specification ends without a closing parenthesis,
305		 * chances are there's something wrong (like a missing
306		 * backslash), so it's better to return failure than allow
307		 * such things to happen
308		 */
309		if (*cp == '\0') {
310			printf("No closing parenthesis in archive "
311			    "specification\n");
312			return (FALSE);
313		}
314
315		/*
316		 * If we didn't move anywhere, we must be done
317		 */
318		if (cp == memName) {
319			break;
320		}
321
322		saveChar = *cp;
323		*cp = '\0';
324
325		/*
326		 * XXX: This should be taken care of intelligently by
327		 * SuffExpandChildren, both for the archive and the member
328		 * portions.
329		 */
330		/*
331		 * If member contains variables, try and substitute for them.
332		 * This will slow down archive specs with dynamic sources, of
333		 * course, since we'll be (non-)substituting them three times,
334		 * but them's the breaks -- we need to do this since
335		 * SuffExpandChildren calls us, otherwise we could assume the
336		 * thing would be taken care of later.
337		 */
338		if (doSubst) {
339			char	*buf;
340			char	*sacrifice;
341			char	*oldMemName = memName;
342			size_t	sz;
343			Buffer	*buf1;
344
345			/*
346			 * Now form an archive spec and recurse to deal with
347			 * nested variables and multi-word variable values....
348			 * The results are just placed at the end of the
349			 * nodeLst we're returning.
350			 */
351			buf1 = Var_Subst(memName, ctxt, TRUE);
352			memName = Buf_Data(buf1);
353
354			sz = strlen(memName) + strlen(libName) + 3;
355			buf = emalloc(sz);
356
357			snprintf(buf, sz, "%s(%s)", libName, memName);
358
359			sacrifice = buf;
360
361			if (strchr(memName, '$') &&
362			    strcmp(memName, oldMemName) == 0) {
363				/*
364				 * Must contain dynamic sources, so we can't
365				 * deal with it now.
366				 * Just create an ARCHV node for the thing and
367				 * let SuffExpandChildren handle it...
368				 */
369				gn = Targ_FindNode(buf, TARG_CREATE);
370
371				if (gn == NULL) {
372					free(buf);
373					Buf_Destroy(buf1, FALSE);
374					return (FALSE);
375				}
376				gn->type |= OP_ARCHV;
377				Lst_AtEnd(nodeLst, (void *)gn);
378			} else if (!Arch_ParseArchive(&sacrifice, nodeLst,
379			    ctxt)) {
380				/*
381				 * Error in nested call -- free buffer and
382				 * return FALSE ourselves.
383				 */
384				free(buf);
385				Buf_Destroy(buf1, FALSE);
386				return (FALSE);
387			}
388
389			/* Free buffer and continue with our work. */
390			free(buf);
391			Buf_Destroy(buf1, FALSE);
392
393		} else if (Dir_HasWildcards(memName)) {
394			Lst	members = Lst_Initializer(members);
395			char	*member;
396			size_t	sz = MAXPATHLEN;
397			size_t	nsz;
398
399			nameBuf = emalloc(sz);
400
401			Path_Expand(memName, &dirSearchPath, &members);
402			while (!Lst_IsEmpty(&members)) {
403				member = Lst_DeQueue(&members);
404				nsz = strlen(libName) + strlen(member) + 3;
405				if (nsz > sz) {
406					sz = nsz * 2;
407					nameBuf = erealloc(nameBuf, sz);
408				}
409
410				snprintf(nameBuf, sz, "%s(%s)",
411				    libName, member);
412				free(member);
413				gn = Targ_FindNode(nameBuf, TARG_CREATE);
414				if (gn == NULL) {
415					free(nameBuf);
416					/* XXXHB Lst_Destroy(&members) */
417					return (FALSE);
418				}
419				/*
420				 * We've found the node, but have to make sure
421				 * the rest of the world knows it's an archive
422				 * member, without having to constantly check
423				 * for parentheses, so we type the thing with
424				 * the OP_ARCHV bit before we place it on the
425				 * end of the provided list.
426				 */
427				gn->type |= OP_ARCHV;
428				Lst_AtEnd(nodeLst, gn);
429			}
430			free(nameBuf);
431		} else {
432			size_t	sz = strlen(libName) + strlen(memName) + 3;
433
434			nameBuf = emalloc(sz);
435			snprintf(nameBuf, sz, "%s(%s)", libName, memName);
436			gn = Targ_FindNode(nameBuf, TARG_CREATE);
437			free(nameBuf);
438			if (gn == NULL) {
439				return (FALSE);
440			}
441			/*
442			 * We've found the node, but have to make sure the
443			 * rest of the world knows it's an archive member,
444			 * without having to constantly check for parentheses,
445			 * so we type the thing with the OP_ARCHV bit before
446			 * we place it on the end of the provided list.
447			 */
448			gn->type |= OP_ARCHV;
449			Lst_AtEnd(nodeLst, gn);
450		}
451		if (doSubst) {
452			free(memName);
453		}
454
455		*cp = saveChar;
456	}
457
458	/*
459	 * If substituted libName, free it now, since we need it no longer.
460	 */
461	if (subLibName) {
462		free(libName);
463	}
464
465	/*
466	 * We promised the pointer would be set up at the next non-space, so
467	 * we must advance cp there before setting *linePtr... (note that on
468	 * entrance to the loop, cp is guaranteed to point at a ')')
469	 */
470	do {
471		cp++;
472	} while (*cp != '\0' && isspace((unsigned char)*cp));
473
474	*linePtr = cp;
475	return (TRUE);
476}
477
478/*
479 * Close an archive file an free all resources
480 */
481static void
482ArchArchiveClose(struct arfile *ar)
483{
484
485	if (ar->nametab != NULL)
486		free(ar->nametab);
487	free(ar->member);
488	if (ar->fp != NULL) {
489		if (fclose(ar->fp) == EOF)
490			ArchError(("%s: close error", ar->fname));
491	}
492	free(ar->fname);
493	free(ar);
494}
495
496/*
497 * Open an archive file.
498 */
499static struct arfile *
500ArchArchiveOpen(const char *archive, const char *mode)
501{
502	struct arfile *ar;
503	char	magic[SARMAG];
504
505	ar = emalloc(sizeof(*ar));
506	ar->fname = estrdup(archive);
507	ar->mlen = 100;
508	ar->member = emalloc(ar->mlen);
509	ar->nametab = NULL;
510	ar->nametablen = 0;
511
512	if ((ar->fp = fopen(ar->fname, mode)) == NULL) {
513		DEBUGM(ARCH, ("%s", ar->fname));
514		ArchArchiveClose(ar);
515		return (NULL);
516	}
517
518	/* read MAGIC */
519	if (fread(magic, SARMAG, 1, ar->fp) != 1 ||
520	    strncmp(magic, ARMAG, SARMAG) != 0) {
521		ArchError(("%s: bad archive magic\n", ar->fname));
522		ArchArchiveClose(ar);
523		return (NULL);
524	}
525
526	ar->pos = 0;
527	return (ar);
528}
529
530/*
531 * Read the next header from the archive. The return value will be +1 if
532 * the header is read successfully, 0 on EOF and -1 if an error happened.
533 * On a successful return sname contains the truncated member name and
534 * member the full name. hdr contains the member header. For the symbol table
535 * names of length 0 are returned. The entry for the file name table is never
536 * returned.
537 */
538static int
539ArchArchiveNext(struct arfile *ar)
540{
541	char	*end;
542	int	have_long_name;
543	u_long	offs;
544	char	*ptr;
545	size_t	ret;
546	char	buf[MAX(sizeof(ar->hdr.ar_size), sizeof(ar->hdr.ar_date)) + 1];
547
548  next:
549	/*
550	 * Seek to the next header.
551	 */
552	if (ar->pos == 0) {
553		ar->pos = SARMAG;
554	} else {
555		ar->pos += sizeof(ar->hdr) + ar->size;
556		if (ar->size % 2 == 1)
557			ar->pos++;
558	}
559
560	if (fseeko(ar->fp, ar->pos, SEEK_SET) == -1) {
561		ArchError(("%s: cannot seek to %jd: %s", ar->fname,
562		    (intmax_t)ar->pos, strerror(errno)));
563		return (-1);
564	}
565
566	/*
567	 * Read next member header
568	 */
569	ret = fread(&ar->hdr, sizeof(ar->hdr), 1, ar->fp);
570	if (ret != 1) {
571		if (feof(ar->fp))
572			return (0);
573		ArchError(("%s: error reading member header: %s", ar->fname,
574		    strerror(errno)));
575		return (-1);
576	}
577	if (strncmp(ar->hdr.ar_fmag, ARFMAG, sizeof(ar->hdr.ar_fmag)) != 0) {
578		ArchError(("%s: bad entry magic", ar->fname));
579		return (-1);
580	}
581
582	/*
583	 * looks like a member - get name by stripping trailing spaces
584	 * and NUL terminating.
585	 */
586	strlcpy(ar->sname, ar->hdr.ar_name, AR_NAMSIZ + 1);
587	for (ptr = ar->sname + AR_NAMSIZ; ptr > ar->sname; ptr--)
588		if (ptr[-1] != ' ')
589			break;
590
591	*ptr = '\0';
592
593	/*
594	 * Parse the size. All entries need to have a size. Be careful
595	 * to not allow buffer overruns.
596	 */
597	strlcpy(buf, ar->hdr.ar_size, sizeof(ar->hdr.ar_size) + 1);
598
599	errno = 0;
600	ar->size = strtoumax(buf, &end, 10);
601	if (errno != 0 || strspn(end, " ") != strlen(end)) {
602		ArchError(("%s: bad size format in archive '%s'",
603		    ar->fname, buf));
604		return (-1);
605	}
606
607	/*
608	 * Look for the extended name table. Do this before parsing
609	 * the date because this table doesn't need a date.
610	 */
611	if (strcmp(ar->sname, BSD_NAMEMAG) == 0 ||
612	    strcmp(ar->sname, SVR4_NAMEMAG) == 0) {
613		/* filename table - read it in */
614		ar->nametablen = ar->size;
615		ar->nametab = emalloc(ar->nametablen);
616
617		ret = fread(ar->nametab, 1, ar->nametablen, ar->fp);
618		if (ret != ar->nametablen) {
619			if (ferror(ar->fp)) {
620				ArchError(("%s: cannot read nametab: %s",
621				    ar->fname, strerror(errno)));
622			} else {
623				ArchError(("%s: cannot read nametab: "
624				    "short read", ar->fname, strerror(errno)));
625			}
626			return (-1);
627		}
628
629		/*
630		 * NUL terminate the entries. Entries are \n terminated
631		 * and may have a trailing / or \.
632		 */
633		ptr = ar->nametab;
634		while (ptr < ar->nametab + ar->nametablen) {
635			if (*ptr == '\n') {
636				if (ptr[-1] == '/' || ptr[-1] == '\\')
637					ptr[-1] = '\0';
638				*ptr = '\0';
639			}
640			ptr++;
641		}
642
643		/* get next archive entry */
644		goto next;
645	}
646
647	/*
648	 * Now parse the modification date. Be careful to not overrun
649	 * buffers.
650	 */
651	strlcpy(buf, ar->hdr.ar_date, sizeof(ar->hdr.ar_date) + 1);
652
653	errno = 0;
654	ar->time = (int64_t)strtoll(buf, &end, 10);
655	if (errno != 0 || strspn(end, " ") != strlen(end)) {
656		ArchError(("%s: bad date format in archive '%s'",
657		    ar->fname, buf));
658		return (-1);
659	}
660
661	/*
662	 * Now check for the symbol table. This should really be the first
663	 * entry, but we don't check this.
664	 */
665	if (strcmp(ar->sname, BSD_RANLIBMAG) == 0 ||
666	    strcmp(ar->sname, SVR4_RANLIBMAG) == 0) {
667		/* symbol table - return a zero length name */
668		ar->member[0] = '\0';
669		ar->sname[0] = '\0';
670		return (1);
671	}
672
673	have_long_name = 0;
674
675	/*
676	 * Look whether this is a long name. There are several variants
677	 * of long names:
678	 *	"#1/12           "	- 12 length of following filename
679	 *	"/17             "	- index into name table
680	 *	" 17             "	- index into name table
681	 * Note that in the last case we must also check that there is no
682	 * slash in the name because of filenames with leading spaces:
683	 *	" 777.o/           "	- filename 777.o
684	 */
685	if (ar->sname[0] == '/' || (ar->sname[0] == ' ' &&
686	    strchr(ar->sname, '/') == NULL)) {
687		/* SVR4 extended name */
688		errno = 0;
689		offs = strtoul(ar->sname + 1, &end, 10);
690		if (errno != 0 || *end != '\0' || offs >= ar->nametablen ||
691		    end == ar->sname + 1) {
692			ArchError(("%s: bad extended name '%s'", ar->fname,
693			    ar->sname));
694			return (-1);
695		}
696
697		/* fetch the name */
698		if (ar->mlen <= strlen(ar->nametab + offs)) {
699			ar->mlen = strlen(ar->nametab + offs) + 1;
700			ar->member = erealloc(ar->member, ar->mlen);
701		}
702		strcpy(ar->member, ar->nametab + offs);
703
704		have_long_name = 1;
705
706	} else if (strncmp(ar->sname, BSD_EXT1, BSD_EXT1LEN) == 0 &&
707	    isdigit(ar->sname[BSD_EXT1LEN])) {
708		/* BSD4.4 extended name */
709		errno = 0;
710		offs = strtoul(ar->sname + BSD_EXT1LEN, &end, 10);
711		if (errno != 0 || *end != '\0' ||
712		    end == ar->sname + BSD_EXT1LEN) {
713			ArchError(("%s: bad extended name '%s'", ar->fname,
714			    ar->sname));
715			return (-1);
716		}
717
718		/* read it from the archive */
719		if (ar->mlen <= offs) {
720			ar->mlen = offs + 1;
721			ar->member = erealloc(ar->member, ar->mlen);
722		}
723		ret = fread(ar->member, 1, offs, ar->fp);
724		if (ret != offs) {
725			if (ferror(ar->fp)) {
726				ArchError(("%s: reading extended name: %s",
727				    ar->fname, strerror(errno)));
728			} else {
729				ArchError(("%s: reading extended name: "
730				    "short read", ar->fname));
731			}
732			return (-1);
733		}
734		ar->member[offs] = '\0';
735
736		have_long_name = 1;
737	}
738
739	/*
740	 * Now remove the trailing slash that Svr4 puts at
741	 * the end of the member name to support trailing spaces in names.
742	 */
743	if (ptr > ar->sname && ptr[-1] == '/')
744		*--ptr = '\0';
745
746	if (!have_long_name) {
747		if (strlen(ar->sname) >= ar->mlen) {
748			ar->mlen = strlen(ar->sname) + 1;
749			ar->member = erealloc(ar->member, ar->mlen);
750		}
751		strcpy(ar->member, ar->sname);
752	}
753
754	return (1);
755}
756
757/*
758 * Touch the current archive member by writing a new header with an
759 * updated timestamp. The return value is 0 for success and -1 for errors.
760 */
761static int
762ArchArchiveTouch(struct arfile *ar, int64_t ts)
763{
764
765	/* seek to our header */
766	if (fseeko(ar->fp, ar->pos, SEEK_SET) == -1) {
767		ArchError(("%s: cannot seek to %jd: %s", ar->fname,
768		    (intmax_t)ar->pos, strerror(errno)));
769		return (-1);
770	}
771
772	/*
773	 * change timestamp, be sure to not NUL-terminated it, but
774	 * to fill with spaces.
775	 */
776	snprintf(ar->hdr.ar_date, sizeof(ar->hdr.ar_date), "%jd",
777	    (intmax_t)ts);
778	memset(ar->hdr.ar_date + strlen(ar->hdr.ar_date),
779	    ' ', sizeof(ar->hdr.ar_date) - strlen(ar->hdr.ar_date));
780
781	if (fwrite(&ar->hdr, sizeof(ar->hdr), 1, ar->fp) != 1) {
782		ArchError(("%s: cannot touch: %s", ar->fname, strerror(errno)));
783		return (-1);
784	}
785	return (0);
786}
787
788/*-
789 *-----------------------------------------------------------------------
790 * ArchFindMember --
791 *	Locate a member of an archive, given the path of the archive and
792 *	the path of the desired member. If the archive is to be modified,
793 *	the mode should be "r+", if not, it should be "r".  The archive
794 *	file is returned positioned at the correct header.
795 *
796 * Results:
797 *	A struct arfile *, opened for reading and, possibly writing,
798 *	positioned at the member's header, or NULL if the member was
799 *	nonexistent.
800 *
801 *-----------------------------------------------------------------------
802 */
803static struct arfile *
804ArchFindMember(const char *archive, const char *member, const char *mode)
805{
806	struct arfile	*ar;
807	const char	*cp;	/* Useful character pointer */
808
809	if ((ar = ArchArchiveOpen(archive, mode)) == NULL)
810		return (NULL);
811
812	/*
813	 * Because of space constraints and similar things, files are archived
814	 * using their final path components, not the entire thing, so we need
815	 * to point 'member' to the final component, if there is one, to make
816	 * the comparisons easier...
817	 */
818	if (member != NULL) {
819		cp = strrchr(member, '/');
820		if (cp != NULL) {
821			member = cp + 1;
822		}
823	}
824
825	while (ArchArchiveNext(ar) > 0) {
826		/*
827		 * When comparing there are actually three cases:
828		 * (1) the name fits into the limit og af_name,
829		 * (2) the name is longer and the archive supports long names,
830		 * (3) the name is longer and the archive doesn't support long
831		 * names.
832		 * Because we don't know whether the archive supports long
833		 * names or not we need to be careful.
834		 */
835		if (member == NULL) {
836			/* special case - symbol table */
837			if (ar->member[0] == '\0')
838				return (ar);
839		} else if (strlen(member) <= AR_NAMSIZ) {
840			/* case (1) */
841			if (strcmp(ar->member, member) == 0)
842				return (ar);
843		} else if (strcmp(ar->member, member) == 0) {
844			/* case (3) */
845			return (ar);
846		} else {
847			/* case (2) */
848			if (strlen(ar->member) == AR_NAMSIZ &&
849			    strncmp(member, ar->member, AR_NAMSIZ) == 0)
850				return (ar);
851		}
852	}
853
854	/* not found */
855	ArchArchiveClose(ar);
856	return (NULL);
857}
858
859/*-
860 *-----------------------------------------------------------------------
861 * ArchStatMember --
862 *	Locate a member of an archive, given the path of the archive and
863 *	the path of the desired member, and a boolean representing whether
864 *	or not the archive should be hashed (if not already hashed).
865 *
866 * Results:
867 *	A pointer to the current struct ar_hdr structure for the member. Note
868 *	That no position is returned, so this is not useful for touching
869 *	archive members. This is mostly because we have no assurances that
870 *	The archive will remain constant after we read all the headers, so
871 *	there's not much point in remembering the position...
872 *
873 * Side Effects:
874 *
875 *-----------------------------------------------------------------------
876 */
877static int64_t
878ArchStatMember(const char *archive, const char *member, Boolean hash)
879{
880	struct arfile	*arf;
881	int64_t		ret;
882	int		t;
883	char		*cp;	/* Useful character pointer */
884	Arch		*ar;	/* Archive descriptor */
885	Hash_Entry	*he;	/* Entry containing member's description */
886	char		copy[AR_NAMSIZ + 1];
887
888	/*
889	 * Because of space constraints and similar things, files are archived
890	 * using their final path components, not the entire thing, so we need
891	 * to point 'member' to the final component, if there is one, to make
892	 * the comparisons easier...
893	 */
894	if (member != NULL) {
895		cp = strrchr(member, '/');
896		if (cp != NULL)
897			member = cp + 1;
898	}
899
900	TAILQ_FOREACH(ar, &archives, link) {
901		if (strcmp(archive, ar->name) == 0)
902			break;
903	}
904	if (ar == NULL) {
905		/* archive not found */
906		if (!hash) {
907			/*
908			 * Caller doesn't want the thing hashed, just use
909			 * ArchFindMember to read the header for the member
910			 * out and close down the stream again.
911			 */
912			arf = ArchFindMember(archive, member, "r");
913			if (arf == NULL) {
914				return (INT64_MIN);
915			}
916			ret = arf->time;
917			ArchArchiveClose(arf);
918			return (ret);
919		}
920
921		/*
922		 * We don't have this archive on the list yet, so we want to
923		 * find out everything that's in it and cache it so we can get
924		 * at it quickly.
925		 */
926		arf = ArchArchiveOpen(archive, "r");
927		if (arf == NULL) {
928			return (INT64_MIN);
929		}
930
931		/* create archive data structure */
932		ar = emalloc(sizeof(*ar));
933		ar->name = estrdup(archive);
934		Hash_InitTable(&ar->members, -1);
935
936		while ((t = ArchArchiveNext(arf)) > 0) {
937			he = Hash_CreateEntry(&ar->members, arf->member, NULL);
938			Hash_SetValue(he, emalloc(sizeof(int64_t)));
939			*(int64_t *)Hash_GetValue(he) = arf->time;
940		}
941
942		ArchArchiveClose(arf);
943
944		if (t < 0) {
945			/* error happened - throw away everything */
946			Hash_DeleteTable(&ar->members);
947			free(ar->name);
948			free(ar);
949			return (INT64_MIN);
950		}
951
952		TAILQ_INSERT_TAIL(&archives, ar, link);
953	}
954
955	/*
956	 * Now that the archive has been read and cached, we can look into
957	 * the hash table to find the desired member's header.
958	 */
959	he = Hash_FindEntry(&ar->members, member);
960	if (he != NULL)
961		return (*(int64_t *)Hash_GetValue (he));
962
963	if (member != NULL && strlen(member) > AR_NAMSIZ) {
964		/* Try truncated name */
965		strlcpy(copy, member, AR_NAMSIZ + 1);
966
967		if ((he = Hash_FindEntry(&ar->members, copy)) != NULL)
968			return (*(int64_t *)Hash_GetValue(he));
969	}
970
971	return (INT64_MIN);
972}
973
974/*-
975 *-----------------------------------------------------------------------
976 * Arch_Touch --
977 *	Touch a member of an archive.
978 *
979 * Results:
980 *	The 'time' field of the member's header is updated.
981 *
982 * Side Effects:
983 *	The modification time of the entire archive is also changed.
984 *	For a library, this could necessitate the re-ranlib'ing of the
985 *	whole thing.
986 *
987 *-----------------------------------------------------------------------
988 */
989void
990Arch_Touch(GNode *gn)
991{
992	struct arfile	*ar;
993
994	ar = ArchFindMember(Var_Value(ARCHIVE, gn),
995	    Var_Value(TARGET, gn), "r+");
996
997	if (ar != NULL) {
998		ArchArchiveTouch(ar, (int64_t)now);
999		ArchArchiveClose(ar);
1000	}
1001}
1002
1003/*-
1004 *-----------------------------------------------------------------------
1005 * Arch_TouchLib --
1006 *	Given a node which represents a library, touch the thing, making
1007 *	sure that the table of contents also is touched.
1008 *
1009 * Results:
1010 *	None.
1011 *
1012 * Side Effects:
1013 *	Both the modification time of the library and of the RANLIBMAG
1014 *	member are set to 'now'.
1015 *
1016 *-----------------------------------------------------------------------
1017 */
1018void
1019Arch_TouchLib(GNode *gn)
1020{
1021	struct arfile	*ar;	/* Open archive */
1022	struct utimbuf	times;	/* Times for utime() call */
1023
1024	ar = ArchFindMember(gn->path, NULL, "r+");
1025	if (ar != NULL) {
1026		ArchArchiveTouch(ar, (int64_t)now);
1027		ArchArchiveClose(ar);
1028
1029		times.actime = times.modtime = now;
1030		utime(gn->path, &times);
1031	}
1032}
1033
1034/*-
1035 *-----------------------------------------------------------------------
1036 * Arch_MTime --
1037 *	Return the modification time of a member of an archive, given its
1038 *	name.
1039 *
1040 * Results:
1041 *	The modification time(seconds).
1042 *	XXXHB this should be a long.
1043 *
1044 * Side Effects:
1045 *	The mtime field of the given node is filled in with the value
1046 *	returned by the function.
1047 *
1048 *-----------------------------------------------------------------------
1049 */
1050int
1051Arch_MTime(GNode *gn)
1052{
1053	int64_t	mtime;
1054
1055	mtime = ArchStatMember(Var_Value(ARCHIVE, gn),
1056	    Var_Value(TARGET, gn), TRUE);
1057
1058	if (mtime == INT_MIN) {
1059		mtime = 0;
1060	}
1061	gn->mtime = (int)mtime;			/* XXX */
1062	return (gn->mtime);
1063}
1064
1065/*-
1066 *-----------------------------------------------------------------------
1067 * Arch_MemMTime --
1068 *	Given a non-existent archive member's node, get its modification
1069 *	time from its archived form, if it exists.
1070 *
1071 * Results:
1072 *	The modification time.
1073 *
1074 * Side Effects:
1075 *	The mtime field is filled in.
1076 *
1077 *-----------------------------------------------------------------------
1078 */
1079int
1080Arch_MemMTime(GNode *gn)
1081{
1082	LstNode	*ln;
1083	GNode	*pgn;
1084	char	*nameStart;
1085	char	*nameEnd;
1086
1087	for (ln = Lst_First(&gn->parents); ln != NULL; ln = Lst_Succ(ln)) {
1088		pgn = Lst_Datum(ln);
1089
1090		if (pgn->type & OP_ARCHV) {
1091			/*
1092			 * If the parent is an archive specification and is
1093			 * being made and its member's name matches the name of
1094			 * the node we were given, record the modification time
1095			 * of the parent in the child. We keep searching its
1096			 * parents in case some other parent requires this
1097			 * child to exist...
1098			 */
1099			nameStart = strchr(pgn->name, '(') + 1;
1100			nameEnd = strchr(nameStart, ')');
1101
1102			if (pgn->make && strncmp(nameStart, gn->name,
1103			    nameEnd - nameStart) == 0) {
1104				gn->mtime = Arch_MTime(pgn);
1105			}
1106		} else if (pgn->make) {
1107			/*
1108			 * Something which isn't a library depends on the
1109			 * existence of this target, so it needs to exist.
1110			 */
1111			gn->mtime = 0;
1112			break;
1113		}
1114	}
1115	return (gn->mtime);
1116}
1117
1118/*-
1119 *-----------------------------------------------------------------------
1120 * Arch_FindLib --
1121 *	Search for a named library along the given search path.
1122 *
1123 * Results:
1124 *	None.
1125 *
1126 * Side Effects:
1127 *	The node's 'path' field is set to the found path (including the
1128 *	actual file name, not -l...). If the system can handle the -L
1129 *	flag when linking (or we cannot find the library), we assume that
1130 *	the user has placed the .LIBRARIES variable in the final linking
1131 *	command (or the linker will know where to find it) and set the
1132 *	TARGET variable for this node to be the node's name. Otherwise,
1133 *	we set the TARGET variable to be the full path of the library,
1134 *	as returned by Path_FindFile.
1135 *
1136 *-----------------------------------------------------------------------
1137 */
1138void
1139Arch_FindLib(GNode *gn, struct Path *path)
1140{
1141	char	*libName;	/* file name for archive */
1142	size_t	sz;
1143
1144	sz = strlen(gn->name) + 4;
1145	libName = emalloc(sz);
1146	snprintf(libName, sz, "lib%s.a", &gn->name[2]);
1147
1148	gn->path = Path_FindFile(libName, path);
1149
1150	free(libName);
1151
1152#ifdef LIBRARIES
1153	Var_Set(TARGET, gn->name, gn);
1154#else
1155	Var_Set(TARGET, gn->path == NULL ? gn->name : gn->path, gn);
1156#endif /* LIBRARIES */
1157}
1158
1159/*-
1160 *-----------------------------------------------------------------------
1161 * Arch_LibOODate --
1162 *	Decide if a node with the OP_LIB attribute is out-of-date. Called
1163 *	from Make_OODate to make its life easier, with the library's
1164 *	graph node.
1165 *
1166 *	There are several ways for a library to be out-of-date that are
1167 *	not available to ordinary files. In addition, there are ways
1168 *	that are open to regular files that are not available to
1169 *	libraries. A library that is only used as a source is never
1170 *	considered out-of-date by itself. This does not preclude the
1171 *	library's modification time from making its parent be out-of-date.
1172 *	A library will be considered out-of-date for any of these reasons,
1173 *	given that it is a target on a dependency line somewhere:
1174 *	    Its modification time is less than that of one of its
1175 *		  sources (gn->mtime < gn->cmtime).
1176 *	    Its modification time is greater than the time at which the
1177 *		  make began (i.e. it's been modified in the course
1178 *		  of the make, probably by archiving).
1179 *	    The modification time of one of its sources is greater than
1180 *		  the one of its RANLIBMAG member (i.e. its table of contents
1181 *		  is out-of-date). We don't compare of the archive time
1182 *		  vs. TOC time because they can be too close. In my
1183 *		  opinion we should not bother with the TOC at all since
1184 *		  this is used by 'ar' rules that affect the data contents
1185 *		  of the archive, not by ranlib rules, which affect the
1186 *		  TOC.
1187 *
1188 * Results:
1189 *	TRUE if the library is out-of-date. FALSE otherwise.
1190 *
1191 * Side Effects:
1192 *	The library will be hashed if it hasn't been already.
1193 *
1194 *-----------------------------------------------------------------------
1195 */
1196Boolean
1197Arch_LibOODate(GNode *gn)
1198{
1199	int64_t	mtime;	/* The table-of-contents's mod time */
1200
1201	if (OP_NOP(gn->type) && Lst_IsEmpty(&gn->children)) {
1202		return (FALSE);
1203	}
1204	if (gn->mtime > now || gn->mtime < gn->cmtime) {
1205		return (TRUE);
1206	}
1207
1208	mtime = ArchStatMember(gn->path, NULL, FALSE);
1209	if (mtime == INT64_MIN) {
1210		/*
1211		 * Not found. A library w/o a table of contents is out-of-date
1212		 */
1213		if (DEBUG(ARCH) || DEBUG(MAKE)) {
1214			Debug("No TOC...");
1215		}
1216		return (TRUE);
1217	}
1218
1219	/* XXX choose one. */
1220	if (DEBUG(ARCH) || DEBUG(MAKE)) {
1221		Debug("TOC modified %s...", Targ_FmtTime(mtime));
1222	}
1223	return (gn->cmtime > mtime);
1224}
1225