| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: arch.c,v 1.152 2020/11/02 18:24:42 rillig Exp $ */ | | 1 | /* $NetBSD: arch.c,v 1.153 2020/11/02 19:07:09 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | | 4 | * Copyright (c) 1988, 1989, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -120,27 +120,27 @@ | | | @@ -120,27 +120,27 @@ |
120 | #include <sys/types.h> | | 120 | #include <sys/types.h> |
121 | #include <sys/stat.h> | | 121 | #include <sys/stat.h> |
122 | #include <sys/time.h> | | 122 | #include <sys/time.h> |
123 | #include <sys/param.h> | | 123 | #include <sys/param.h> |
124 | | | 124 | |
125 | #include <ar.h> | | 125 | #include <ar.h> |
126 | #include <utime.h> | | 126 | #include <utime.h> |
127 | | | 127 | |
128 | #include "make.h" | | 128 | #include "make.h" |
129 | #include "dir.h" | | 129 | #include "dir.h" |
130 | #include "config.h" | | 130 | #include "config.h" |
131 | | | 131 | |
132 | /* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */ | | 132 | /* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */ |
133 | MAKE_RCSID("$NetBSD: arch.c,v 1.152 2020/11/02 18:24:42 rillig Exp $"); | | 133 | MAKE_RCSID("$NetBSD: arch.c,v 1.153 2020/11/02 19:07:09 rillig Exp $"); |
134 | | | 134 | |
135 | #ifdef TARGET_MACHINE | | 135 | #ifdef TARGET_MACHINE |
136 | #undef MAKE_MACHINE | | 136 | #undef MAKE_MACHINE |
137 | #define MAKE_MACHINE TARGET_MACHINE | | 137 | #define MAKE_MACHINE TARGET_MACHINE |
138 | #endif | | 138 | #endif |
139 | #ifdef TARGET_MACHINE_ARCH | | 139 | #ifdef TARGET_MACHINE_ARCH |
140 | #undef MAKE_MACHINE_ARCH | | 140 | #undef MAKE_MACHINE_ARCH |
141 | #define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH | | 141 | #define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH |
142 | #endif | | 142 | #endif |
143 | | | 143 | |
144 | typedef struct List ArchList; | | 144 | typedef struct List ArchList; |
145 | typedef struct ListNode ArchListNode; | | 145 | typedef struct ListNode ArchListNode; |
146 | | | 146 | |
| @@ -179,49 +179,49 @@ ArchFree(void *ap) | | | @@ -179,49 +179,49 @@ ArchFree(void *ap) |
179 | free(a); | | 179 | free(a); |
180 | } | | 180 | } |
181 | #endif | | 181 | #endif |
182 | | | 182 | |
183 | | | 183 | |
184 | /*- | | 184 | /*- |
185 | *----------------------------------------------------------------------- | | 185 | *----------------------------------------------------------------------- |
186 | * Arch_ParseArchive -- | | 186 | * Arch_ParseArchive -- |
187 | * Parse the archive specification in the given line and find/create | | 187 | * Parse the archive specification in the given line and find/create |
188 | * the nodes for the specified archive members, placing their nodes | | 188 | * the nodes for the specified archive members, placing their nodes |
189 | * on the given list. | | 189 | * on the given list. |
190 | * | | 190 | * |
191 | * Input: | | 191 | * Input: |
192 | * linePtr Pointer to start of specification | | 192 | * pp Pointer to start of specification, updated |
193 | * nodeLst Lst on which to place the nodes | | 193 | * nodeLst Lst on which to place the nodes |
194 | * ctxt Context in which to expand variables | | 194 | * ctxt Context in which to expand variables |
195 | * | | 195 | * |
196 | * Results: | | 196 | * Results: |
197 | * TRUE if it was a valid specification. The linePtr is updated | | 197 | * TRUE if it was a valid specification. The pp is updated |
198 | * to point to the first non-space after the archive spec. The | | 198 | * to point to the first non-space after the archive spec. The |
199 | * nodes for the members are placed on the given list. | | 199 | * nodes for the members are placed on the given list. |
200 | *----------------------------------------------------------------------- | | 200 | *----------------------------------------------------------------------- |
201 | */ | | 201 | */ |
202 | Boolean | | 202 | Boolean |
203 | Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, GNode *ctxt) | | 203 | Arch_ParseArchive(char **pp, GNodeList *nodeLst, GNode *ctxt) |
204 | { | | 204 | { |
205 | char *cp; /* Pointer into line */ | | 205 | char *cp; /* Pointer into line */ |
206 | GNode *gn; /* New node */ | | 206 | GNode *gn; /* New node */ |
207 | char *libName; /* Library-part of specification */ | | 207 | char *libName; /* Library-part of specification */ |
208 | char *libName_freeIt = NULL; | | 208 | char *libName_freeIt = NULL; |
209 | char *memName; /* Member-part of specification */ | | 209 | char *memName; /* Member-part of specification */ |
210 | char saveChar; /* Ending delimiter of member-name */ | | 210 | char saveChar; /* Ending delimiter of member-name */ |
211 | Boolean subLibName; /* TRUE if libName should have/had | | 211 | Boolean subLibName; /* TRUE if libName should have/had |
212 | * variable substitution performed on it */ | | 212 | * variable substitution performed on it */ |
213 | | | 213 | |
214 | libName = *linePtr; | | 214 | libName = *pp; |
215 | | | 215 | |
216 | subLibName = FALSE; | | 216 | subLibName = FALSE; |
217 | | | 217 | |
218 | for (cp = libName; *cp != '(' && *cp != '\0';) { | | 218 | for (cp = libName; *cp != '(' && *cp != '\0';) { |
219 | if (*cp == '$') { | | 219 | if (*cp == '$') { |
220 | /* | | 220 | /* |
221 | * Variable spec, so call the Var module to parse the puppy | | 221 | * Variable spec, so call the Var module to parse the puppy |
222 | * so we can safely advance beyond it... | | 222 | * so we can safely advance beyond it... |
223 | */ | | 223 | */ |
224 | const char *nested_p = cp; | | 224 | const char *nested_p = cp; |
225 | void *result_freeIt; | | 225 | void *result_freeIt; |
226 | const char *result; | | 226 | const char *result; |
227 | Boolean isError; | | 227 | Boolean isError; |
| @@ -384,29 +384,29 @@ Arch_ParseArchive(char **linePtr, GNodeL | | | @@ -384,29 +384,29 @@ Arch_ParseArchive(char **linePtr, GNodeL |
384 | gn->type |= OP_ARCHV; | | 384 | gn->type |= OP_ARCHV; |
385 | Lst_Append(nodeLst, gn); | | 385 | Lst_Append(nodeLst, gn); |
386 | } | | 386 | } |
387 | if (doSubst) { | | 387 | if (doSubst) { |
388 | free(memName); | | 388 | free(memName); |
389 | } | | 389 | } |
390 | | | 390 | |
391 | *cp = saveChar; | | 391 | *cp = saveChar; |
392 | } | | 392 | } |
393 | | | 393 | |
394 | free(libName_freeIt); | | 394 | free(libName_freeIt); |
395 | | | 395 | |
396 | cp++; /* skip the ')' */ | | 396 | cp++; /* skip the ')' */ |
397 | /* We promised that linePtr would be set up at the next non-space. */ | | 397 | /* We promised that pp would be set up at the next non-space. */ |
398 | pp_skip_whitespace(&cp); | | 398 | pp_skip_whitespace(&cp); |
399 | *linePtr = cp; | | 399 | *pp = cp; |
400 | return TRUE; | | 400 | return TRUE; |
401 | } | | 401 | } |
402 | | | 402 | |
403 | /* Locate a member of an archive, given the path of the archive and the path | | 403 | /* Locate a member of an archive, given the path of the archive and the path |
404 | * of the desired member. | | 404 | * of the desired member. |
405 | * | | 405 | * |
406 | * Input: | | 406 | * Input: |
407 | * archive Path to the archive | | 407 | * archive Path to the archive |
408 | * member Name of member; only its basename is used. | | 408 | * member Name of member; only its basename is used. |
409 | * hash TRUE if archive should be hashed if not already so. | | 409 | * hash TRUE if archive should be hashed if not already so. |
410 | * | | 410 | * |
411 | * Results: | | 411 | * Results: |
412 | * The ar_hdr for the member. | | 412 | * The ar_hdr for the member. |
| @@ -423,28 +423,28 @@ ArchStatMember(const char *archive, cons | | | @@ -423,28 +423,28 @@ ArchStatMember(const char *archive, cons |
423 | struct ar_hdr arh; /* archive-member header for reading archive */ | | 423 | struct ar_hdr arh; /* archive-member header for reading archive */ |
424 | char memName[MAXPATHLEN + 1]; | | 424 | char memName[MAXPATHLEN + 1]; |
425 | /* Current member name while hashing. */ | | 425 | /* Current member name while hashing. */ |
426 | | | 426 | |
427 | /* | | 427 | /* |
428 | * Because of space constraints and similar things, files are archived | | 428 | * Because of space constraints and similar things, files are archived |
429 | * using their basename, not the entire path. | | 429 | * using their basename, not the entire path. |
430 | */ | | 430 | */ |
431 | const char *lastSlash = strrchr(member, '/'); | | 431 | const char *lastSlash = strrchr(member, '/'); |
432 | if (lastSlash != NULL) | | 432 | if (lastSlash != NULL) |
433 | member = lastSlash + 1; | | 433 | member = lastSlash + 1; |
434 | | | 434 | |
435 | for (ln = archives->first; ln != NULL; ln = ln->next) { | | 435 | for (ln = archives->first; ln != NULL; ln = ln->next) { |
436 | const Arch *archPtr = ln->datum; | | 436 | const Arch *a = ln->datum; |
437 | if (strcmp(archPtr->name, archive) == 0) | | 437 | if (strcmp(a->name, archive) == 0) |
438 | break; | | 438 | break; |
439 | } | | 439 | } |
440 | | | 440 | |
441 | if (ln != NULL) { | | 441 | if (ln != NULL) { |
442 | struct ar_hdr *hdr; | | 442 | struct ar_hdr *hdr; |
443 | | | 443 | |
444 | ar = ln->datum; | | 444 | ar = ln->datum; |
445 | hdr = HashTable_FindValue(&ar->members, member); | | 445 | hdr = HashTable_FindValue(&ar->members, member); |
446 | if (hdr != NULL) | | 446 | if (hdr != NULL) |
447 | return hdr; | | 447 | return hdr; |
448 | | | 448 | |
449 | { | | 449 | { |
450 | /* Try truncated name */ | | 450 | /* Try truncated name */ |
| @@ -684,37 +684,37 @@ ArchSVR4Entry(Arch *ar, char *name, size | | | @@ -684,37 +684,37 @@ ArchSVR4Entry(Arch *ar, char *name, size |
684 | | | 684 | |
685 | /*- | | 685 | /*- |
686 | *----------------------------------------------------------------------- | | 686 | *----------------------------------------------------------------------- |
687 | * ArchFindMember -- | | 687 | * ArchFindMember -- |
688 | * Locate a member of an archive, given the path of the archive and | | 688 | * Locate a member of an archive, given the path of the archive and |
689 | * the path of the desired member. If the archive is to be modified, | | 689 | * the path of the desired member. If the archive is to be modified, |
690 | * the mode should be "r+", if not, it should be "r". | | 690 | * the mode should be "r+", if not, it should be "r". |
691 | * The passed struct ar_hdr structure is filled in. | | 691 | * The passed struct ar_hdr structure is filled in. |
692 | * | | 692 | * |
693 | * Input: | | 693 | * Input: |
694 | * archive Path to the archive | | 694 | * archive Path to the archive |
695 | * member Name of member. If it is a path, only the last | | 695 | * member Name of member. If it is a path, only the last |
696 | * component is used. | | 696 | * component is used. |
697 | * arhPtr Pointer to header structure to be filled in | | 697 | * out_arh Archive header to be filled in |
698 | * mode The mode for opening the stream | | 698 | * mode The mode for opening the stream |
699 | * | | 699 | * |
700 | * Results: | | 700 | * Results: |
701 | * An FILE *, opened for reading and writing, positioned at the | | 701 | * An FILE *, opened for reading and writing, positioned at the |
702 | * start of the member's struct ar_hdr, or NULL if the member was | | 702 | * start of the member's struct ar_hdr, or NULL if the member was |
703 | * nonexistent. The current struct ar_hdr for member. | | 703 | * nonexistent. The current struct ar_hdr for member. |
704 | *----------------------------------------------------------------------- | | 704 | *----------------------------------------------------------------------- |
705 | */ | | 705 | */ |
706 | static FILE * | | 706 | static FILE * |
707 | ArchFindMember(const char *archive, const char *member, struct ar_hdr *arhPtr, | | 707 | ArchFindMember(const char *archive, const char *member, struct ar_hdr *out_arh, |
708 | const char *mode) | | 708 | const char *mode) |
709 | { | | 709 | { |
710 | FILE *arch; /* Stream to archive */ | | 710 | FILE *arch; /* Stream to archive */ |
711 | int size; /* Size of archive member */ | | 711 | int size; /* Size of archive member */ |
712 | char magic[SARMAG]; | | 712 | char magic[SARMAG]; |
713 | size_t len, tlen; | | 713 | size_t len, tlen; |
714 | const char *lastSlash; | | 714 | const char *lastSlash; |
715 | | | 715 | |
716 | arch = fopen(archive, mode); | | 716 | arch = fopen(archive, mode); |
717 | if (arch == NULL) | | 717 | if (arch == NULL) |
718 | return NULL; | | 718 | return NULL; |
719 | | | 719 | |
720 | /* | | 720 | /* |
| @@ -726,75 +726,76 @@ ArchFindMember(const char *archive, cons | | | @@ -726,75 +726,76 @@ ArchFindMember(const char *archive, cons |
726 | fclose(arch); | | 726 | fclose(arch); |
727 | return NULL; | | 727 | return NULL; |
728 | } | | 728 | } |
729 | | | 729 | |
730 | /* | | 730 | /* |
731 | * Because of space constraints and similar things, files are archived | | 731 | * Because of space constraints and similar things, files are archived |
732 | * using their basename, not the entire path. | | 732 | * using their basename, not the entire path. |
733 | */ | | 733 | */ |
734 | lastSlash = strrchr(member, '/'); | | 734 | lastSlash = strrchr(member, '/'); |
735 | if (lastSlash != NULL) | | 735 | if (lastSlash != NULL) |
736 | member = lastSlash + 1; | | 736 | member = lastSlash + 1; |
737 | | | 737 | |
738 | len = tlen = strlen(member); | | 738 | len = tlen = strlen(member); |
739 | if (len > sizeof(arhPtr->ar_name)) { | | 739 | if (len > sizeof(out_arh->ar_name)) { |
740 | tlen = sizeof(arhPtr->ar_name); | | 740 | tlen = sizeof(out_arh->ar_name); |
741 | } | | 741 | } |
742 | | | 742 | |
743 | while (fread((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) == 1) { | | 743 | while (fread((char *)out_arh, sizeof(struct ar_hdr), 1, arch) == 1) { |
744 | | | 744 | |
745 | if (strncmp(arhPtr->ar_fmag, ARFMAG, sizeof(arhPtr->ar_fmag)) != 0) { | | 745 | if (strncmp(out_arh->ar_fmag, ARFMAG, sizeof(out_arh->ar_fmag)) != 0) { |
746 | /* | | 746 | /* |
747 | * The header is bogus, so the archive is bad | | 747 | * The header is bogus, so the archive is bad |
748 | * and there's no way we can recover... | | 748 | * and there's no way we can recover... |
749 | */ | | 749 | */ |
750 | fclose(arch); | | 750 | fclose(arch); |
751 | return NULL; | | 751 | return NULL; |
752 | } | | 752 | } |
753 | | | 753 | |
754 | if (strncmp(member, arhPtr->ar_name, tlen) == 0) { | | 754 | if (strncmp(member, out_arh->ar_name, tlen) == 0) { |
755 | /* | | 755 | /* |
756 | * If the member's name doesn't take up the entire 'name' field, | | 756 | * If the member's name doesn't take up the entire 'name' field, |
757 | * we have to be careful of matching prefixes. Names are space- | | 757 | * we have to be careful of matching prefixes. Names are space- |
758 | * padded to the right, so if the character in 'name' at the end | | 758 | * padded to the right, so if the character in 'name' at the end |
759 | * of the matched string is anything but a space, this isn't the | | 759 | * of the matched string is anything but a space, this isn't the |
760 | * member we sought. | | 760 | * member we sought. |
761 | */ | | 761 | */ |
762 | if (tlen != sizeof arhPtr->ar_name && arhPtr->ar_name[tlen] != ' ') | | 762 | if (tlen != sizeof out_arh->ar_name && |
| | | 763 | out_arh->ar_name[tlen] != ' ') |
763 | goto skip; | | 764 | goto skip; |
764 | | | 765 | |
765 | /* | | 766 | /* |
766 | * To make life easier, we reposition the file at the start | | 767 | * To make life easier, we reposition the file at the start |
767 | * of the header we just read before we return the stream. | | 768 | * of the header we just read before we return the stream. |
768 | * In a more general situation, it might be better to leave | | 769 | * In a more general situation, it might be better to leave |
769 | * the file at the actual member, rather than its header, but | | 770 | * the file at the actual member, rather than its header, but |
770 | * not here... | | 771 | * not here... |
771 | */ | | 772 | */ |
772 | if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) { | | 773 | if (fseek(arch, -(long)sizeof(struct ar_hdr), SEEK_CUR) != 0) { |
773 | fclose(arch); | | 774 | fclose(arch); |
774 | return NULL; | | 775 | return NULL; |
775 | } | | 776 | } |
776 | return arch; | | 777 | return arch; |
777 | } | | 778 | } |
778 | | | 779 | |
779 | #ifdef AR_EFMT1 | | 780 | #ifdef AR_EFMT1 |
780 | /* | | 781 | /* |
781 | * BSD 4.4 extended AR format: #1/<namelen>, with name as the | | 782 | * BSD 4.4 extended AR format: #1/<namelen>, with name as the |
782 | * first <namelen> bytes of the file | | 783 | * first <namelen> bytes of the file |
783 | */ | | 784 | */ |
784 | if (strncmp(arhPtr->ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 && | | 785 | if (strncmp(out_arh->ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 && |
785 | ch_isdigit(arhPtr->ar_name[sizeof(AR_EFMT1) - 1])) | | 786 | ch_isdigit(out_arh->ar_name[sizeof(AR_EFMT1) - 1])) |
786 | { | | 787 | { |
787 | int elen = atoi(&arhPtr->ar_name[sizeof(AR_EFMT1) - 1]); | | 788 | int elen = atoi(&out_arh->ar_name[sizeof(AR_EFMT1) - 1]); |
788 | char ename[MAXPATHLEN + 1]; | | 789 | char ename[MAXPATHLEN + 1]; |
789 | | | 790 | |
790 | if ((unsigned int)elen > MAXPATHLEN) { | | 791 | if ((unsigned int)elen > MAXPATHLEN) { |
791 | fclose(arch); | | 792 | fclose(arch); |
792 | return NULL; | | 793 | return NULL; |
793 | } | | 794 | } |
794 | if (fread(ename, (size_t)elen, 1, arch) != 1) { | | 795 | if (fread(ename, (size_t)elen, 1, arch) != 1) { |
795 | fclose(arch); | | 796 | fclose(arch); |
796 | return NULL; | | 797 | return NULL; |
797 | } | | 798 | } |
798 | ename[elen] = '\0'; | | 799 | ename[elen] = '\0'; |
799 | if (DEBUG(ARCH) || DEBUG(MAKE)) { | | 800 | if (DEBUG(ARCH) || DEBUG(MAKE)) { |
800 | debug_printf("ArchFind: Extended format entry for %s\n", ename); | | 801 | debug_printf("ArchFind: Extended format entry for %s\n", ename); |
| @@ -813,28 +814,28 @@ ArchFindMember(const char *archive, cons | | | @@ -813,28 +814,28 @@ ArchFindMember(const char *archive, cons |
813 | return NULL; | | 814 | return NULL; |
814 | } | | 815 | } |
815 | } | | 816 | } |
816 | #endif | | 817 | #endif |
817 | | | 818 | |
818 | skip: | | 819 | skip: |
819 | /* | | 820 | /* |
820 | * This isn't the member we're after, so we need to advance the | | 821 | * This isn't the member we're after, so we need to advance the |
821 | * stream's pointer to the start of the next header. Files are | | 822 | * stream's pointer to the start of the next header. Files are |
822 | * padded with newlines to an even-byte boundary, so we need to | | 823 | * padded with newlines to an even-byte boundary, so we need to |
823 | * extract the size of the file from the 'size' field of the | | 824 | * extract the size of the file from the 'size' field of the |
824 | * header and round it up during the seek. | | 825 | * header and round it up during the seek. |
825 | */ | | 826 | */ |
826 | arhPtr->ar_size[sizeof(arhPtr->ar_size) - 1] = '\0'; | | 827 | out_arh->ar_size[sizeof(out_arh->ar_size) - 1] = '\0'; |
827 | size = (int)strtol(arhPtr->ar_size, NULL, 10); | | 828 | size = (int)strtol(out_arh->ar_size, NULL, 10); |
828 | if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) { | | 829 | if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) { |
829 | fclose(arch); | | 830 | fclose(arch); |
830 | return NULL; | | 831 | return NULL; |
831 | } | | 832 | } |
832 | } | | 833 | } |
833 | | | 834 | |
834 | /* | | 835 | /* |
835 | * We've looked everywhere, but the member is not to be found. Close the | | 836 | * We've looked everywhere, but the member is not to be found. Close the |
836 | * archive and return NULL -- an error. | | 837 | * archive and return NULL -- an error. |
837 | */ | | 838 | */ |
838 | fclose(arch); | | 839 | fclose(arch); |
839 | return NULL; | | 840 | return NULL; |
840 | } | | 841 | } |
| @@ -902,32 +903,32 @@ Arch_TouchLib(GNode *gn) | | | @@ -902,32 +903,32 @@ Arch_TouchLib(GNode *gn) |
902 | (void)gn; | | 903 | (void)gn; |
903 | #endif | | 904 | #endif |
904 | } | | 905 | } |
905 | | | 906 | |
906 | /* Return the modification time of a member of an archive. The mtime field | | 907 | /* Return the modification time of a member of an archive. The mtime field |
907 | * of the given node is filled in with the value returned by the function. | | 908 | * of the given node is filled in with the value returned by the function. |
908 | * | | 909 | * |
909 | * Input: | | 910 | * Input: |
910 | * gn Node describing archive member | | 911 | * gn Node describing archive member |
911 | */ | | 912 | */ |
912 | time_t | | 913 | time_t |
913 | Arch_MTime(GNode *gn) | | 914 | Arch_MTime(GNode *gn) |
914 | { | | 915 | { |
915 | struct ar_hdr *arhPtr; /* Header of desired member */ | | 916 | struct ar_hdr *arh; /* Header of desired member */ |
916 | time_t modTime; /* Modification time as an integer */ | | 917 | time_t modTime; /* Modification time as an integer */ |
917 | | | 918 | |
918 | arhPtr = ArchStatMember(GNode_VarArchive(gn), GNode_VarMember(gn), TRUE); | | 919 | arh = ArchStatMember(GNode_VarArchive(gn), GNode_VarMember(gn), TRUE); |
919 | if (arhPtr != NULL) { | | 920 | if (arh != NULL) { |
920 | modTime = (time_t)strtol(arhPtr->ar_date, NULL, 10); | | 921 | modTime = (time_t)strtol(arh->ar_date, NULL, 10); |
921 | } else { | | 922 | } else { |
922 | modTime = 0; | | 923 | modTime = 0; |
923 | } | | 924 | } |
924 | | | 925 | |
925 | gn->mtime = modTime; | | 926 | gn->mtime = modTime; |
926 | return modTime; | | 927 | return modTime; |
927 | } | | 928 | } |
928 | | | 929 | |
929 | /* Given a non-existent archive member's node, get its modification time from | | 930 | /* Given a non-existent archive member's node, get its modification time from |
930 | * its archived form, if it exists. gn->mtime is filled in as well. */ | | 931 | * its archived form, if it exists. gn->mtime is filled in as well. */ |
931 | time_t | | 932 | time_t |
932 | Arch_MemMTime(GNode *gn) | | 933 | Arch_MemMTime(GNode *gn) |
933 | { | | 934 | { |
| @@ -1032,33 +1033,33 @@ Arch_LibOODate(GNode *gn) | | | @@ -1032,33 +1033,33 @@ Arch_LibOODate(GNode *gn) |
1032 | Boolean oodate; | | 1033 | Boolean oodate; |
1033 | | | 1034 | |
1034 | if (gn->type & OP_PHONY) { | | 1035 | if (gn->type & OP_PHONY) { |
1035 | oodate = TRUE; | | 1036 | oodate = TRUE; |
1036 | } else if (!GNode_IsTarget(gn) && Lst_IsEmpty(gn->children)) { | | 1037 | } else if (!GNode_IsTarget(gn) && Lst_IsEmpty(gn->children)) { |
1037 | oodate = FALSE; | | 1038 | oodate = FALSE; |
1038 | } else if ((!Lst_IsEmpty(gn->children) && gn->youngestChild == NULL) || | | 1039 | } else if ((!Lst_IsEmpty(gn->children) && gn->youngestChild == NULL) || |
1039 | (gn->mtime > now) || | | 1040 | (gn->mtime > now) || |
1040 | (gn->youngestChild != NULL && | | 1041 | (gn->youngestChild != NULL && |
1041 | gn->mtime < gn->youngestChild->mtime)) { | | 1042 | gn->mtime < gn->youngestChild->mtime)) { |
1042 | oodate = TRUE; | | 1043 | oodate = TRUE; |
1043 | } else { | | 1044 | } else { |
1044 | #ifdef RANLIBMAG | | 1045 | #ifdef RANLIBMAG |
1045 | struct ar_hdr *arhPtr; /* Header for __.SYMDEF */ | | 1046 | struct ar_hdr *arh; /* Header for __.SYMDEF */ |
1046 | int modTimeTOC; /* The table-of-contents's mod time */ | | 1047 | int modTimeTOC; /* The table-of-contents's mod time */ |
1047 | | | 1048 | |
1048 | arhPtr = ArchStatMember(gn->path, RANLIBMAG, FALSE); | | 1049 | arh = ArchStatMember(gn->path, RANLIBMAG, FALSE); |
1049 | | | 1050 | |
1050 | if (arhPtr != NULL) { | | 1051 | if (arh != NULL) { |
1051 | modTimeTOC = (int)strtol(arhPtr->ar_date, NULL, 10); | | 1052 | modTimeTOC = (int)strtol(arh->ar_date, NULL, 10); |
1052 | | | 1053 | |
1053 | if (DEBUG(ARCH) || DEBUG(MAKE)) { | | 1054 | if (DEBUG(ARCH) || DEBUG(MAKE)) { |
1054 | debug_printf("%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); | | 1055 | debug_printf("%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); |
1055 | } | | 1056 | } |
1056 | oodate = (gn->youngestChild == NULL || gn->youngestChild->mtime > modTimeTOC); | | 1057 | oodate = (gn->youngestChild == NULL || gn->youngestChild->mtime > modTimeTOC); |
1057 | } else { | | 1058 | } else { |
1058 | /* | | 1059 | /* |
1059 | * A library w/o a table of contents is out-of-date | | 1060 | * A library w/o a table of contents is out-of-date |
1060 | */ | | 1061 | */ |
1061 | if (DEBUG(ARCH) || DEBUG(MAKE)) { | | 1062 | if (DEBUG(ARCH) || DEBUG(MAKE)) { |
1062 | debug_printf("No t.o.c...."); | | 1063 | debug_printf("No t.o.c...."); |
1063 | } | | 1064 | } |
1064 | oodate = TRUE; | | 1065 | oodate = TRUE; |