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