]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.bin/make/arch.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.bin / make / arch.c
1 /*-
2  * Copyright (c) 1988, 1989, 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1989 by Berkeley Softworks
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * 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$");
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
117 typedef 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 */
130 static 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  */
139 struct 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 */
178 Boolean 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  */
213 Boolean
214 Arch_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  */
481 static void
482 ArchArchiveClose(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  */
499 static struct arfile *
500 ArchArchiveOpen(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  */
538 static int
539 ArchArchiveNext(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  */
761 static int
762 ArchArchiveTouch(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  */
803 static struct arfile *
804 ArchFindMember(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  */
877 static int64_t
878 ArchStatMember(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  */
989 void
990 Arch_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  */
1018 void
1019 Arch_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  */
1050 int
1051 Arch_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  */
1079 int
1080 Arch_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  */
1138 void
1139 Arch_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  */
1196 Boolean
1197 Arch_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 }