version 1.42, 2000/11/27 20:37:16 |
version 1.43, 2001/03/02 16:57:26 |
|
|
#define MACHINE_ARCH TARGET_MACHINE_ARCH |
#define MACHINE_ARCH TARGET_MACHINE_ARCH |
#endif |
#endif |
|
|
static struct hash archives; /* Archives we've already examined */ |
static struct ohash archives; /* Archives we've already examined */ |
|
|
typedef struct Arch_ { |
typedef struct Arch_ { |
struct hash members; /* All the members of this archive, as |
struct ohash members; /* All the members of this archive, as |
* struct arch_member entries. */ |
* struct arch_member entries. */ |
char name[1]; /* Archive name */ |
char name[1]; /* Archive name */ |
} Arch; |
} Arch; |
|
|
char name[1]; /* Member name. */ |
char name[1]; /* Member name. */ |
}; |
}; |
|
|
static struct hash_info members_info = { |
static struct ohash_info members_info = { |
offsetof(struct arch_member, name), NULL, |
offsetof(struct arch_member, name), NULL, |
hash_alloc, hash_free, element_alloc |
hash_alloc, hash_free, element_alloc |
}; |
}; |
|
|
static struct hash_info arch_info = { |
static struct ohash_info arch_info = { |
offsetof(Arch, name), NULL, hash_alloc, hash_free, element_alloc |
offsetof(Arch, name), NULL, hash_alloc, hash_free, element_alloc |
}; |
}; |
|
|
|
|
const char *end = NULL; |
const char *end = NULL; |
struct arch_member *n; |
struct arch_member *n; |
|
|
n = hash_create_entry(&members_info, name, &end); |
n = ohash_create_entry(&members_info, name, &end); |
/* XXX ar entries are NOT null terminated. */ |
/* XXX ar entries are NOT null terminated. */ |
memcpy(n->date, &(hdr->ar_date), AR_DATE_SIZE); |
memcpy(n->date, &(hdr->ar_date), AR_DATE_SIZE); |
n->date[AR_DATE_SIZE] = '\0'; |
n->date[AR_DATE_SIZE] = '\0'; |
|
|
unsigned int i; |
unsigned int i; |
|
|
/* Free memory from hash entries */ |
/* Free memory from hash entries */ |
for (mem = hash_first(&a->members, &i); mem != NULL; |
for (mem = ohash_first(&a->members, &i); mem != NULL; |
mem = hash_next(&a->members, &i)) |
mem = ohash_next(&a->members, &i)) |
free(mem); |
free(mem); |
|
|
hash_delete(&a->members); |
ohash_delete(&a->members); |
free(a); |
free(a); |
} |
} |
#endif |
#endif |
|
|
return NULL; |
return NULL; |
} |
} |
|
|
ar = hash_create_entry(&arch_info, archive, &end); |
ar = ohash_create_entry(&arch_info, archive, &end); |
hash_init(&ar->members, 8, &members_info); |
ohash_init(&ar->members, 8, &members_info); |
|
|
for (;;) { |
for (;;) { |
size_t n; |
size_t n; |
|
|
} |
} |
#endif |
#endif |
|
|
hash_insert(&ar->members, |
ohash_insert(&ar->members, |
hash_qlookup(&ar->members, memName), |
ohash_qlookup(&ar->members, memName), |
new_arch_member(&arh, memName)); |
new_arch_member(&arh, memName)); |
} |
} |
if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) |
if (fseek(arch, (size + 1) & ~1, SEEK_CUR) != 0) |
|
|
} |
} |
|
|
fclose(arch); |
fclose(arch); |
hash_delete(&ar->members); |
ohash_delete(&ar->members); |
#ifdef SVR4ARCHIVES |
#ifdef SVR4ARCHIVES |
efree(list.fnametab); |
efree(list.fnametab); |
#endif |
#endif |
|
|
member = cp + 1; |
member = cp + 1; |
|
|
/* Try to find archive in cache. */ |
/* Try to find archive in cache. */ |
slot = hash_qlookupi(&archives, archive, &end); |
slot = ohash_qlookupi(&archives, archive, &end); |
ar = hash_find(&archives, slot); |
ar = ohash_find(&archives, slot); |
|
|
/* If not found, get it now. */ |
/* If not found, get it now. */ |
if (ar == NULL) { |
if (ar == NULL) { |
|
|
} |
} |
ar = read_archive(archive, end); |
ar = read_archive(archive, end); |
if (ar != NULL) |
if (ar != NULL) |
hash_insert(&archives, slot, ar); |
ohash_insert(&archives, slot, ar); |
} |
} |
/* If archive was found, get entry we seek. */ |
/* If archive was found, get entry we seek. */ |
if (ar != NULL) { |
if (ar != NULL) { |
struct arch_member *he; |
struct arch_member *he; |
end = NULL; |
end = NULL; |
|
|
he = hash_find(&ar->members, hash_qlookupi(&ar->members, member, &end)); |
he = ohash_find(&ar->members, ohash_qlookupi(&ar->members, member, &end)); |
if (he != NULL) |
if (he != NULL) |
return mtime_of_member(he); |
return mtime_of_member(he); |
else { |
else { |
if (end - member > AR_NAME_SIZE) { |
if (end - member > AR_NAME_SIZE) { |
/* Try truncated name */ |
/* Try truncated name */ |
end = member + AR_NAME_SIZE; |
end = member + AR_NAME_SIZE; |
he = hash_find(&ar->members, |
he = ohash_find(&ar->members, |
hash_qlookupi(&ar->members, member, &end)); |
ohash_qlookupi(&ar->members, member, &end)); |
if (he != NULL) |
if (he != NULL) |
return mtime_of_member(he); |
return mtime_of_member(he); |
} |
} |
|
|
void |
void |
Arch_Init() |
Arch_Init() |
{ |
{ |
hash_init(&archives, 4, &arch_info); |
ohash_init(&archives, 4, &arch_info); |
} |
} |
|
|
|
|
|
|
Arch *e; |
Arch *e; |
unsigned int i; |
unsigned int i; |
|
|
for (e = hash_first(&archives, &i); e != NULL; |
for (e = ohash_first(&archives, &i); e != NULL; |
e = hash_next(&archives, &i)) |
e = ohash_next(&archives, &i)) |
ArchFree(e); |
ArchFree(e); |
hash_delete(&archives); |
ohash_delete(&archives); |
#endif |
#endif |
} |
} |
|
|