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