HashTable *load_map(char *fn) { HashTable *h = HashTableCreate(65536, HASH_DYNAMIC_SIZE | HASH_POOL_ITEMS); FILE *fp; char line[8192]; if (NULL == (fp = fopen(fn, "r"))) { perror(fn); return NULL; } while(fgets(line, 8192, fp)) { char *cp, *from, *to; HashData hd; for (from = cp = line; *cp && !isspace(*cp); cp++); if (!*cp) { fprintf(stderr, "Malformed line '%s'\n", line); return NULL; } *cp++ = 0; for (to = cp; isprint(*cp); cp++); *cp++ = 0; hd.p = strdup(to); if (!HashTableAdd(h, from, strlen(from), hd, NULL)) return NULL; } close(fp); return h; }
static int HashTableTestFull02 (void) { int result = 0; HashTable *ht = HashTableInit(32, HashTableGenericHash, NULL, NULL); if (ht == NULL) goto end; int r = HashTableAdd(ht, "test", 4); if (r != 0) goto end; char *rp = HashTableLookup(ht, "test", 4); if (rp == NULL) goto end; r = HashTableRemove(ht, "test2", 5); if (r == 0) goto end; /* all is good! */ result = 1; end: if (ht != NULL) HashTableFree(ht); return result; }
/** * \brief Parses a line from the reference config file and adds it to Reference * Config hash table DetectEngineCtx->reference_conf_ht. * * \param rawstr Pointer to the string to be parsed. * \param de_ctx Pointer to the Detection Engine Context. * * \retval 0 On success. * \retval -1 On failure. */ static int SCRConfAddReference(char *rawstr, DetectEngineCtx *de_ctx) { char system[64]; char url[1024]; SCRConfReference *ref_new = NULL; SCRConfReference *ref_lookup = NULL; #define MAX_SUBSTRINGS 30 int ret = 0; int ov[MAX_SUBSTRINGS]; ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30); if (ret < 0) { SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in " "reference.config file"); goto error; } /* retrieve the reference system */ ret = pcre_copy_substring((char *)rawstr, ov, 30, 1, system, sizeof(system)); if (ret < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring() failed"); goto error; } /* retrieve the reference url */ ret = pcre_copy_substring((char *)rawstr, ov, 30, 2, url, sizeof(url)); if (ret < 0) { SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring() failed"); goto error; } /* Create a new instance of the parsed Reference string */ ref_new = SCRConfAllocSCRConfReference(system, url); if (ref_new == NULL) goto error; /* Check if the Reference is present in the HashTable. In case it's present * ignore it, as it's a duplicate. If not present, add it to the table */ ref_lookup = HashTableLookup(de_ctx->reference_conf_ht, ref_new, 0); if (ref_lookup == NULL) { if (HashTableAdd(de_ctx->reference_conf_ht, ref_new, 0) < 0) { SCLogDebug("HashTable Add failed"); } } else { SCLogDebug("Duplicate reference found inside reference.config"); SCRConfDeAllocSCRConfReference(ref_new); } return 0; error: return -1; }
/* * Removes some or all tags from some or all contigs. * If the contig list or tag list is blank it implies all contigs or all tags. * * Returns 0 on success * -1 on failure */ int delete_tags(GapIO *io, int ncontigs, contig_list_t *contigs, char *tag_list, int verbose) { HashTable *h = NULL; int ret = 0; /* Hash tag types */ if (tag_list && *tag_list) { int i; if (SetActiveTags(tag_list) == -1) { return -1; } h = HashTableCreate(32, 0); for (i = 0; i < number_of_active_tags; i++) { HashData hd; hd.i = 0; HashTableAdd(h, active_tag_types[i], 4, hd, NULL); } } /* Iterate over contig list or all contigs */ if (verbose) vfuncheader("Delete Tags"); if (ncontigs) { int i; for (i = 0; i < ncontigs; i++) { contig_t *c = cache_search(io, GT_Contig, contigs[i].contig); vmessage("Scanning contig %d of %d (%s)\n", i+1, ncontigs, c->name); ret |= delete_tag_single_contig(io, contigs[i].contig, h, verbose); UpdateTextOutput(); cache_flush(io); } } else { int i; tg_rec *order = ArrayBase(tg_rec, io->contig_order); for (i = 0; i < NumContigs(io); i++) { contig_t *c = cache_search(io, GT_Contig, order[i]); vmessage("Scanning contig %d of %d (%s)\n", i+1, NumContigs(io), c->name); ret |= delete_tag_single_contig(io, order[i], h, verbose); UpdateTextOutput(); cache_flush(io); } } SetActiveTags(""); if (h) HashTableDestroy(h, 0); return ret; }
HashTable *readSnpFile(char *snp_file) { FILE *fp; HashTable *snp_hash; static const int line_size = 8192; char line[line_size]; size_t count = 0; char last_chrom[100] = ""; display("reading snp file %s\n", snp_file); fp = fopen(snp_file, "rb"); if (NULL == fp) { die("ERROR: can't open known snp file %s: %s\n", snp_file, strerror(errno)); } if (NULL == (snp_hash = HashTableCreate(0, HASH_DYNAMIC_SIZE | HASH_FUNC_JENKINS3))) { die("ERROR: creating snp hash table\n"); } while (fgets(line, line_size, fp)) { char key[100]; HashData hd; int bin, start, end; char chrom[100]; if (4 != sscanf(line, "%d\t%s\t%d\t%d", &bin, chrom, &start, &end)) { die("ERROR: reading snp file\n%s\n", line); } /* N.B rod start is 0 based */ snprintf(key, sizeof(key), "%s:%d", chrom, start); hd.i = 0; if (NULL == HashTableAdd(snp_hash, key, strlen(key), hd, NULL)) { die("ERROR: building snp hash table\n"); } if (strcmp(chrom, last_chrom)) { strcpy(last_chrom, chrom); count = 0; } count++; } fclose(fp); return snp_hash; }
static int HashTableTestAdd02 (void) { int result = 0; HashTable *ht = HashTableInit(32, HashTableGenericHash, NULL, NULL); if (ht == NULL) goto end; int r = HashTableAdd(ht, NULL, 4); if (r == 0) goto end; /* all is good! */ result = 1; end: if (ht != NULL) HashTableFree(ht); return result; }
void construct_hash(HashFile *hf) { int i; for (i = 0; i < nfiles; i++) { HashData hd; HashFileItem *hfi = (HashFileItem *)calloc(1, sizeof(*hfi)); /* Just use the last head/foot defined as we only allow 1 at the mo. */ hfi->header = hf->nheaders; hfi->footer = hf->nfooters; hfi->pos = files[i].pos; hfi->size = files[i].size; hfi->archive = files[i].archive; hd.p = hfi; HashTableAdd(hf->h, files[i].member, strlen(files[i].member), hd, NULL); } }
void cram_stats_add(cram_stats *st, int32_t val) { st->nsamp++; //assert(val >= 0); if (val < MAX_STAT_VAL && val >= 0) { st->freqs[val]++; } else { HashItem *hi; if (!st->h) { st->h = HashTableCreate(2048, HASH_DYNAMIC_SIZE|HASH_NONVOLATILE_KEYS|HASH_INT_KEYS); } if ((hi = HashTableSearch(st->h, (char *)(size_t)val, 4))) { hi->data.i++; } else { HashData hd; hd.i = 1; HashTableAdd(st->h, (char *)(size_t)val, 4, hd, NULL); } } }
/* * process one BAM record, and store accumulated results in 'results' */ int seqchksum_processRecord(bam1_t *rec, HASH_TYPE hash, chksum_results_t *results) { uint32_t crc = 0; uint16_t aflags = rec->core.flag; uint8_t *seq = get_read(rec); uint8_t *qual = get_quality(rec); uint16_t flag_mask = BAM_FPAIRED | BAM_FREAD1 | BAM_FREAD2; uint8_t flags = (aflags & flag_mask) & 0xFF; bool pass = !(aflags & BAM_FQCFAIL);; char *qname = bam_get_qname(rec); uint8_t *tag; char *rgid; HashItem *hi; HashData hd; int newitem; digest_line_t *dline_all; digest_line_t *dline; // look up the RG tag tag = bam_aux_get(rec, "RG"); //hd.p = malloc(sizeof(digest_line_t)); if (tag) rgid = bam_aux2Z(tag); else rgid = ""; hd.p = NULL; hi = HashTableAdd(results->rgHash, rgid, 0, hd, &newitem); if (newitem) { hi->data.p = malloc(sizeof(digest_line_t)); dline = hi->data.p; init_digest_line(hash,dline); } else { dline = hi->data.p; } dline_all = &(results->all); // flags + sequence chksum update_crc(&crc,&flags,1); update_crc(&crc,seq,strlen((char*)seq)); update_digest_line(hash, pass, dline, crc, 0); update_digest_line(hash, pass, dline_all, crc, 0); // flags + sequence + quality chksum (don't reset crc, just add quality) update_crc(&crc,qual,strlen((char*)qual)); update_digest_line(hash, pass, dline, crc, 2); update_digest_line(hash, pass, dline_all, crc, 2); // name + flags + sequence chksum crc = 0; update_crc(&crc, (uint8_t *)qname, strlen(qname)+1); update_crc(&crc, &flags, 1); update_crc(&crc,seq,strlen((char*)seq)); update_digest_line(hash, pass, dline, crc, 1); update_digest_line(hash, pass, dline_all, crc, 1); // flags + sequence + tags chksum crc = 0; update_crc(&crc, &flags, 1); update_crc(&crc,seq,strlen((char*)seq)); tag = bam_aux_get(rec,"BC"); if (tag) update_crc(&crc,tag-2,aux_type2size(tag)+3); tag = bam_aux_get(rec,"FI"); if (tag) update_crc(&crc,tag-2,aux_type2size(tag)+3); tag = bam_aux_get(rec,"QT"); if (tag) update_crc(&crc,tag-2,aux_type2size(tag)+3); tag = bam_aux_get(rec,"RT"); if (tag) update_crc(&crc,tag-2,aux_type2size(tag)+3); tag = bam_aux_get(rec,"TC"); if (tag) update_crc(&crc,tag-2,aux_type2size(tag)+3); update_digest_line(hash, pass, dline, crc, 3); update_digest_line(hash, pass, dline_all, crc, 3); free(seq); free(qual); return 0; }
static NTSTATUS GnttabMapForeignPages( IN PINTERFACE Interface, IN USHORT Domain, IN ULONG NumberPages, IN PULONG References, IN BOOLEAN ReadOnly, OUT PHYSICAL_ADDRESS *Address ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; LONG PageIndex; PHYSICAL_ADDRESS PageAddress; PXENBUS_GNTTAB_MAP_ENTRY MapEntry; NTSTATUS status; status = FdoAllocateIoSpace(Context->Fdo, NumberPages * PAGE_SIZE, Address); if (!NT_SUCCESS(status)) goto fail1; MapEntry = __GnttabAllocate(FIELD_OFFSET(XENBUS_GNTTAB_MAP_ENTRY, MapHandles) + (NumberPages * sizeof (ULONG))); status = STATUS_NO_MEMORY; if (MapEntry == NULL) goto fail2; PageAddress.QuadPart = Address->QuadPart; MapEntry->NumberPages = NumberPages; for (PageIndex = 0; PageIndex < (LONG)NumberPages; PageIndex++) { status = GrantTableMapForeignPage(Domain, References[PageIndex], PageAddress, ReadOnly, &MapEntry->MapHandles[PageIndex]); if (!NT_SUCCESS(status)) goto fail3; PageAddress.QuadPart += PAGE_SIZE; } status = HashTableAdd(Context->MapTable, (ULONG_PTR)Address->QuadPart, (ULONG_PTR)MapEntry); if (!NT_SUCCESS(status)) goto fail4; return STATUS_SUCCESS; fail4: Error("fail4\n"); fail3: Error("fail3\n"); while (--PageIndex >= 0) { PageAddress.QuadPart -= PAGE_SIZE; (VOID) GrantTableUnmapForeignPage(MapEntry->MapHandles[PageIndex], PageAddress); } __GnttabFree(MapEntry); fail2: Error("fail2\n"); FdoFreeIoSpace(Context->Fdo, *Address, NumberPages * PAGE_SIZE); fail1: Error("fail1: (%08x)\n", status); return status; }
/** * \brief Parses a line from the classification file and adds it to Classtype * hash table in DetectEngineCtx, i.e. DetectEngineCtx->class_conf_ht. * * \param rawstr Pointer to the string to be parsed. * \param index Relative index of the string to be parsed. * \param de_ctx Pointer to the Detection Engine Context. * * \retval 0 On success. * \retval -1 On failure. */ int SCClassConfAddClasstype(char *rawstr, uint8_t index, DetectEngineCtx *de_ctx) { const char *ct_name = NULL; const char *ct_desc = NULL; const char *ct_priority_str = NULL; int ct_priority = 0; uint8_t ct_id = index; SCClassConfClasstype *ct_new = NULL; SCClassConfClasstype *ct_lookup = NULL; #define MAX_SUBSTRINGS 30 int ret = 0; int ov[MAX_SUBSTRINGS]; ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30); if (ret < 0) { SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid Classtype in " "classification.config file"); goto error; } /* retrieve the classtype name */ ret = pcre_get_substring((char *)rawstr, ov, 30, 1, &ct_name); if (ret < 0) { SCLogInfo("pcre_get_substring() failed"); goto error; } /* retrieve the classtype description */ ret = pcre_get_substring((char *)rawstr, ov, 30, 2, &ct_desc); if (ret < 0) { SCLogInfo("pcre_get_substring() failed"); goto error; } /* retrieve the classtype priority */ ret = pcre_get_substring((char *)rawstr, ov, 30, 3, &ct_priority_str); if (ret < 0) { SCLogInfo("pcre_get_substring() failed"); goto error; } if (ct_priority_str == NULL) { goto error; } ct_priority = atoi(ct_priority_str); /* Create a new instance of the parsed Classtype string */ ct_new = SCClassConfAllocClasstype(ct_id, ct_name, ct_desc, ct_priority); if (ct_new == NULL) goto error; /* Check if the Classtype is present in the HashTable. In case it's present * ignore it, as it is a duplicate. If not present, add it to the table */ ct_lookup = HashTableLookup(de_ctx->class_conf_ht, ct_new, 0); if (ct_lookup == NULL) { if (HashTableAdd(de_ctx->class_conf_ht, ct_new, 0) < 0) SCLogDebug("HashTable Add failed"); } else { SCLogDebug("Duplicate classtype found inside classification.config"); if (ct_new->classtype_desc) SCFree(ct_new->classtype_desc); if (ct_new->classtype) SCFree(ct_new->classtype); SCFree(ct_new); } if (ct_name) SCFree((char *)ct_name); if (ct_desc) SCFree((char *)ct_desc); if (ct_priority_str) SCFree((char *)ct_priority_str); return 0; error: if (ct_name) SCFree((char *)ct_name); if (ct_desc) SCFree((char *)ct_desc); if (ct_priority_str) SCFree((char *)ct_priority_str); return -1; }
/* * Complements a scaffold; both complementing each contig within it and * reversing the order of contigs in the scaffold. * * Returns 0 on success * -1 on failure */ int complement_scaffold(GapIO *io, tg_rec srec) { scaffold_t *f; int i, j, nc = ArrayMax(io->contig_order); scaffold_member_t *contigs; tg_rec *crecs; HashTable *h; reg_order ro; reg_buffer_start rs; reg_buffer_end re; if (!(f = cache_search(io, GT_Scaffold, srec))) return -1; if (!(f = cache_rw(io, f))) return -1; cache_incr(io, f); /* Complement contigs */ contigs = ArrayBase(scaffold_member_t, f->contig); for (i = 0; i < ArrayMax(f->contig); i++) { complement_contig(io, contigs[i].rec); } /* Reverse the order of the contigs in the scaffold array */ for (i = 0, j = ArrayMax(f->contig)-1; i < j; i++, j--) { scaffold_member_t cr1 = contigs[i]; contigs[i] = contigs[j]; contigs[j] = cr1; } /* * Reverse the order of contigs in the contig_order array too. * This is the part that really matters. It's also hard as the contigs * in the contig order array could be in any order and not adjacent. * For our purposes we'll just ensure the contigs in this scaffold in * the contig order array match our freshly complemented scaffold * ordering. * * We initially build a hash table of contigs in this scaffold, and * then iterate through contig_order copying out the new contigs whenever * one matches. */ h = HashTableCreate(nc, 0); for (i = 0; i < ArrayMax(f->contig); i++) { HashData hd; hd.i = 0; HashTableAdd(h, (char *)&contigs[i].rec, sizeof(tg_rec), hd, NULL); } /* Replace any contig matching the scaffold with the new order */ crecs = ArrayBase(tg_rec, io->contig_order); for (i = j = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; crecs[i] = contigs[j++].rec; } /* Send event messages around */ rs.job = REG_BUFFER_START; for (i = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; contig_notify(io, crecs[i], (reg_data *)&rs); } ro.job = REG_ORDER; for (i = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; ro.pos = i+1; contig_notify(io, crecs[i], (reg_data *)&ro); } /* Notify the end of our updates */ re.job = REG_BUFFER_END; for (i = 0; i < nc; i++) { HashItem *hi; if (!(hi = HashTableSearch(h, (char *)&crecs[i], sizeof(tg_rec)))) continue; contig_notify(io, crecs[i], (reg_data *)&re); } HashTableDestroy(h, 0); cache_decr(io, f); return 0; }
/* * Parse the REGN chunk, add to regn HASH * * Returns corresponding HashItem * from regn Hash */ HashItem *parse_regn(ztr_t *z, ztr_chunk_t *chunk, HashTable *regn_hash) { char key[1024]; char *name; HashItem *hi; regn_t *regn; size_t l; uncompress_chunk(z, chunk); /* the hash key is a combination of the region names and boundaries */ name = ztr_lookup_mdata_value(z, chunk, "NAME"); l = snprintf(key, sizeof(key), "names=%s", name); if( chunk->dlength ){ int nbndy = (chunk->dlength-1)/4; uint4 *bndy = (uint4 *)(chunk->data+1); int ibndy; for (ibndy=0; ibndy<nbndy; ibndy++) { if( ibndy ) l += snprintf(key + l, sizeof(key) - l, ";%d", be_int4(bndy[ibndy])); else l += snprintf(key + l, sizeof(key) - l, " boundaries=%d", be_int4(bndy[ibndy])); } } if (NULL == (hi = (HashTableSearch(regn_hash, key, strlen(key))))) { int iregion, nregions = 0; char *coord; char *cp1; uint4 bndy[MAX_REGIONS]; int ibndy, nbndy = 0; HashData hd; if( NULL == (regn = (regn_t *)malloc(sizeof(regn_t)))) { return NULL; } coord = ztr_lookup_mdata_value(z, chunk, "COORD"); regn->coord = (NULL == coord ? 'B' : *coord ); regn->region_names = strdup(name); cp1 = strtok (regn->region_names,";"); while(cp1) { char *cp2; if(NULL == (cp2 = strchr(cp1,':'))) { fprintf(stderr, "Invalid region name/code pair %s\n", cp1); return NULL; } *cp2++ = '\0'; regn->name[nregions] = cp1; regn->code[nregions] = *cp2; nregions++; cp1 = strtok (NULL, ";"); } regn->nregions = nregions; if( chunk->dlength ) { nbndy = (chunk->dlength-1)/4; memcpy(bndy, chunk->data+1, chunk->dlength-1); } for( iregion=0, ibndy=0; iregion<nregions; iregion++) { /* start = (start + length of previous region) or 0 if no previous region */ /* length = (next boundary - start of region) or -1 if no next boundary */ if( regn->code[iregion] == 'E' ){ /* no sequence, length = 0 */ regn->start[iregion] = (iregion ? (regn->start[iregion-1] + regn->length[iregion-1]) : 0); regn->length[iregion] = 0; }else{ if( ibndy > nbndy ){ fprintf(stderr, "More name/code pairs than boundaries\n"); return NULL; } regn->start[iregion] = (iregion ? (regn->start[iregion-1] + regn->length[iregion-1]) : 0); regn->length[iregion] = (ibndy == nbndy ? -1 : (be_int4(bndy[ibndy])-regn->start[iregion])); ibndy++; } } regn->count = 1; hd.p = regn; if (NULL == (hi = HashTableAdd(regn_hash, key, strlen(key), hd, NULL))) { free(regn->region_names); free(regn); return NULL; } } else { regn = (regn_t *)(hi->data.p); regn->count++; } return hi; }
int main(int argc, char **argv) { HashFile *hf; sff_common_header *ch; sff_read_header *rh; int i, dot, arg; char *sff; char hdr[31]; uint64_t index_offset = 0; uint32_t index_size, index_skipped; FILE *fp, *fpout = NULL; int copy_archive = 1; /* process command line arguments of the form -arg */ for (argc--, argv++; argc > 0; argc--, argv++) { if (**argv != '-' || strcmp(*argv, "--") == 0) break; if (strcmp(*argv, "-o") == 0 && argc > 1) { if (NULL == (fpout = fopen(argv[1], "wb+"))) { perror(argv[1]); return 1; } argv++; argc--; } else if (strcmp(*argv, "-t") == 0) { copy_archive = 0; } else if (**argv == '-') { usage(); } } if (argc < 1) usage(); if (copy_archive == 0 && argc != 1) { fprintf(stderr, "-t option only supported with a single sff argument\n"); return 1; } /* Create the hash table */ hf = HashFileCreate(0, HASH_DYNAMIC_SIZE); hf->nheaders = 0; hf->headers = NULL; for (arg = 0; arg < argc; arg++) { /* open (and read) the entire sff file */ sff = argv[arg]; printf("Indexing %s:\n", sff); if (fpout) { if (NULL == (fp = fopen(sff, "rb"))) { perror(sff); return 1; } } else { if (NULL == (fp = fopen(sff, "rb+"))) { perror(sff); return 1; } } /* Read the common header */ ch = fread_sff_common_header(fp); if (ch->index_len && !fpout) { fprintf(stderr, "Archive already contains index.\nReplacing the" " index requires the \"-o outfile\" option.\n"); return 1; } /* Add the SFF common header as a hash file-header */ hf->nheaders++; hf->headers = (HashFileSection *)realloc(hf->headers, hf->nheaders * sizeof(*hf->headers)); hf->headers[hf->nheaders-1].pos = 0; hf->headers[hf->nheaders-1].size = ch->header_len; hf->headers[hf->nheaders-1].cached_data = NULL; /* Read the index items, adding to the hash */ index_skipped = 0; dot = 0; printf(" |\r|"); for (i = 0; i < ch->nreads; i++) { int dlen; uint32_t offset; HashData hd; HashFileItem *hfi; if (i >= dot * (ch->nreads/69)) { putchar('.'); fflush(stdout); dot++; } /* Skip old index if present */ offset = ftell(fp); if (offset == ch->index_offset) { fseek(fp, ch->index_len, SEEK_CUR); index_skipped = ch->index_len; continue; } hfi = (HashFileItem *)calloc(1, sizeof(*hfi)); rh = fread_sff_read_header(fp); dlen = (2*ch->flow_len + 3*rh->nbases + 7) & ~7; fseek(fp, dlen, SEEK_CUR); hfi->header = hf->nheaders; hfi->footer = 0; hfi->pos = offset - index_skipped; hfi->size = (ftell(fp) - index_skipped) - hfi->pos; hd.p = hfi; HashTableAdd(hf->h, rh->name, rh->name_len, hd, NULL); } printf("\n"); HashTableStats(hf->h, stdout); index_offset = ftell(fp) - index_skipped; /* Copy the archive if needed, minus the old index */ if (fpout && copy_archive) { char block[8192]; size_t len; uint64_t pos = 0; printf("\nCopying archive\n"); fseek(fp, 0, SEEK_SET); while (len = fread(block, 1, 8192, fp)) { /* Skip previous index */ if (pos < ch->index_offset && pos+len > ch->index_offset) { len = ch->index_offset - pos; fseek(fp, ch->index_offset + ch->index_len, SEEK_SET); } if (len && len != fwrite(block, 1, len, fpout)) { fprintf(stderr, "Failed to output new archive\n"); return 1; } pos += len; } } if (!fpout) { /* Save the hash */ printf("Saving index\n"); fseek(fp, 0, SEEK_END); index_size = HashFileSave(hf, fp, 0); HashFileDestroy(hf); /* Update the common header */ fseek(fp, 0, SEEK_SET); fread(hdr, 1, 31, fp); *(uint64_t *)(hdr+8) = be_int8(index_offset); *(uint32_t *)(hdr+16) = be_int4(index_size); fseek(fp, 0, SEEK_SET); fwrite(hdr, 1, 31, fp); } fclose(fp); } if (fpout) { /* Save the hash */ printf("Saving index\n"); if (!copy_archive) { hf->archive = strdup(argv[0]); index_offset = 0; } fseek(fpout, 0, SEEK_END); index_size = HashFileSave(hf, fpout, 0); HashFileDestroy(hf); /* Update the common header to indicate index location */ if (copy_archive) { fseek(fpout, 0, SEEK_SET); fread(hdr, 1, 31, fpout); *(uint64_t *)(hdr+8) = be_int8(index_offset); *(uint32_t *)(hdr+16) = be_int4(index_size); fseek(fpout, 0, SEEK_SET); fwrite(hdr, 1, 31, fpout); } fclose(fpout); } return 0; }