version 1.8, 1996/10/17 19:08:44 |
version 1.9, 1996/11/30 21:08:49 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
/* $NetBSD: arch.c,v 1.16 1996/08/13 16:42:00 christos Exp $ */ |
/* $NetBSD: arch.c,v 1.17 1996/11/06 17:58:59 christos Exp $ */ |
|
|
/* |
/* |
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
* Copyright (c) 1988, 1989, 1990, 1993 |
* Copyright (c) 1988, 1989 by Adam de Boor |
* The Regents of the University of California. All rights reserved. |
* Copyright (c) 1989 by Berkeley Softworks |
* Copyright (c) 1989 by Berkeley Softworks |
* All rights reserved. |
* All rights reserved. |
* |
* |
|
|
|
|
#ifndef lint |
#ifndef lint |
#if 0 |
#if 0 |
static char sccsid[] = "@(#)arch.c 5.7 (Berkeley) 12/28/90"; |
static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94"; |
static char rcsid[] = "$NetBSD: arch.c,v 1.14 1996/03/12 18:04:27 christos Exp $"; |
|
#else |
#else |
static char rcsid[] = "$OpenBSD$"; |
static char rcsid[] = "$OpenBSD$"; |
#endif |
#endif |
|
|
#include <utime.h> |
#include <utime.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
|
#include <fcntl.h> |
#include "make.h" |
#include "make.h" |
#include "hash.h" |
#include "hash.h" |
#include "dir.h" |
#include "dir.h" |
|
|
Arch *a = (Arch *) ap; |
Arch *a = (Arch *) ap; |
Hash_Search search; |
Hash_Search search; |
Hash_Entry *entry; |
Hash_Entry *entry; |
|
|
/* Free memory from hash entries */ |
/* Free memory from hash entries */ |
for (entry = Hash_EnumFirst(&a->members, &search); |
for (entry = Hash_EnumFirst(&a->members, &search); |
entry != (Hash_Entry *)NULL; |
entry != (Hash_Entry *)NULL; |
entry = Hash_EnumNext(&search)) |
entry = Hash_EnumNext(&search)) |
|
|
Hash_DeleteTable(&a->members); |
Hash_DeleteTable(&a->members); |
free((Address) a); |
free((Address) a); |
} |
} |
|
|
|
|
|
|
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Arch_ParseArchive -- |
* Arch_ParseArchive -- |
|
|
* variable substitution performed on it */ |
* variable substitution performed on it */ |
|
|
libName = *linePtr; |
libName = *linePtr; |
|
|
subLibName = FALSE; |
subLibName = FALSE; |
|
|
for (cp = libName; *cp != '(' && *cp != '\0'; cp++) { |
for (cp = libName; *cp != '(' && *cp != '\0'; cp++) { |
|
|
int length; |
int length; |
Boolean freeIt; |
Boolean freeIt; |
char *result; |
char *result; |
|
|
result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt); |
result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt); |
if (result == var_Error) { |
if (result == var_Error) { |
return(FAILURE); |
return(FAILURE); |
} else { |
} else { |
subLibName = TRUE; |
subLibName = TRUE; |
} |
} |
|
|
if (freeIt) { |
if (freeIt) { |
free(result); |
free(result); |
} |
} |
|
|
if (subLibName) { |
if (subLibName) { |
libName = Var_Subst(NULL, libName, ctxt, TRUE); |
libName = Var_Subst(NULL, libName, ctxt, TRUE); |
} |
} |
|
|
|
|
|
|
for (;;) { |
for (;;) { |
/* |
/* |
* First skip to the start of the member's name, mark that |
* First skip to the start of the member's name, mark that |
|
|
char *buf; |
char *buf; |
char *sacrifice; |
char *sacrifice; |
char *oldMemName = memName; |
char *oldMemName = memName; |
|
|
memName = Var_Subst(NULL, memName, ctxt, TRUE); |
memName = Var_Subst(NULL, memName, ctxt, TRUE); |
|
|
/* |
/* |
|
|
Dir_Expand(memName, dirSearchPath, members); |
Dir_Expand(memName, dirSearchPath, members); |
while (!Lst_IsEmpty(members)) { |
while (!Lst_IsEmpty(members)) { |
member = (char *)Lst_DeQueue(members); |
member = (char *)Lst_DeQueue(members); |
|
|
sprintf(nameBuf, "%s(%s)", libName, member); |
sprintf(nameBuf, "%s(%s)", libName, member); |
free(member); |
free(member); |
gn = Targ_FindNode (nameBuf, TARG_CREATE); |
gn = Targ_FindNode (nameBuf, TARG_CREATE); |
|
|
if (doSubst) { |
if (doSubst) { |
free(memName); |
free(memName); |
} |
} |
|
|
*cp = saveChar; |
*cp = saveChar; |
} |
} |
|
|
|
|
if (arch == (FILE *) NULL) { |
if (arch == (FILE *) NULL) { |
return ((struct ar_hdr *) NULL); |
return ((struct ar_hdr *) NULL); |
} |
} |
|
|
/* |
/* |
* We use the ARMAG string to make sure this is an archive we |
* We use the ARMAG string to make sure this is an archive we |
* can handle... |
* can handle... |
|
|
ar->fnamesize = 0; |
ar->fnamesize = 0; |
Hash_InitTable (&ar->members, -1); |
Hash_InitTable (&ar->members, -1); |
memName[AR_MAX_NAME_LEN] = '\0'; |
memName[AR_MAX_NAME_LEN] = '\0'; |
|
|
while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) { |
while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) { |
if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) { |
if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) { |
/* |
/* |
|
|
if (arch == (FILE *) NULL) { |
if (arch == (FILE *) NULL) { |
return ((FILE *) NULL); |
return ((FILE *) NULL); |
} |
} |
|
|
/* |
/* |
* We use the ARMAG string to make sure this is an archive we |
* We use the ARMAG string to make sure this is an archive we |
* can handle... |
* can handle... |
|
|
if (len > sizeof (arhPtr->ar_name)) { |
if (len > sizeof (arhPtr->ar_name)) { |
tlen = sizeof (arhPtr->ar_name); |
tlen = sizeof (arhPtr->ar_name); |
} |
} |
|
|
while (fread ((char *)arhPtr, sizeof (struct ar_hdr), 1, arch) == 1) { |
while (fread ((char *)arhPtr, sizeof (struct ar_hdr), 1, arch) == 1) { |
if (strncmp(arhPtr->ar_fmag, ARFMAG, sizeof (arhPtr->ar_fmag) ) != 0) { |
if (strncmp(arhPtr->ar_fmag, ARFMAG, sizeof (arhPtr->ar_fmag) ) != 0) { |
/* |
/* |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Arch_FindLib -- |
* Arch_FindLib -- |
* Search for a library along the given search path. |
* Search for a library along the given search path. |
* |
* |
* Results: |
* Results: |
* None. |
* None. |
|
|
* opinion we should not bother with the TOC at all since |
* opinion we should not bother with the TOC at all since |
* this is used by 'ar' rules that affect the data contents |
* this is used by 'ar' rules that affect the data contents |
* of the archive, not by ranlib rules, which affect the |
* of the archive, not by ranlib rules, which affect the |
* TOC. |
* TOC. |
* |
* |
* Results: |
* Results: |
* TRUE if the library is out-of-date. FALSE otherwise. |
* TRUE if the library is out-of-date. FALSE otherwise. |
|
|
GNode *gn; /* The library's graph node */ |
GNode *gn; /* The library's graph node */ |
{ |
{ |
Boolean oodate; |
Boolean oodate; |
|
|
if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) { |
if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) { |
oodate = FALSE; |
oodate = FALSE; |
} else if ((gn->mtime > now) || (gn->mtime < gn->cmtime) || !gn->mtime) { |
} else if ((gn->mtime > now) || (gn->mtime < gn->cmtime) || !gn->mtime) { |
|
|
Arch_End () |
Arch_End () |
{ |
{ |
Lst_Destroy(archives, ArchFree); |
Lst_Destroy(archives, ArchFree); |
|
} |
|
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* Arch_IsLib -- |
|
* Check if the node is a library |
|
* |
|
* Results: |
|
* True or False. |
|
* |
|
* Side Effects: |
|
* None. |
|
* |
|
*----------------------------------------------------------------------- |
|
*/ |
|
int |
|
Arch_IsLib(gn) |
|
GNode *gn; |
|
{ |
|
static const char armag[] = "!<arch>\n"; |
|
char buf[sizeof(armag)-1]; |
|
int fd; |
|
|
|
if ((fd = open(gn->path, O_RDONLY)) == -1) |
|
return FALSE; |
|
|
|
if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { |
|
(void) close(fd); |
|
return FALSE; |
|
} |
|
|
|
(void) close(fd); |
|
|
|
return memcmp(buf, armag, sizeof(buf)) == 0; |
} |
} |