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