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