int read_srf(srf_t *srf, char *srf_name, Settings *opts) { int type; off_t pos; Previous_data seen = { NULL, 0, NULL, 0, NULL, 0 }; Trace_reader trc = { 0, 0, 0, NULL, NULL, 0, NULL, NULL }; do { if ((pos = ftello(srf->fp)) < 0) { printf("Couldn't ftello() on %s: %s\n", srf_name, strerror(errno)); return -1; } switch (type = srf_next_block_type(srf)) { case -1: /* EOF */ return 0; case SRFB_CONTAINER: printf("Found container header at %zd\n", pos); if (0 != srf_read_cont_hdr(srf, &srf->ch)) { printf("srf_read_cont_hdr failed for %s", srf_name); return -1; } break; case SRFB_XML: printf("Found xml block at %zd\n", pos); if (0 != srf_read_xml(srf, &srf->xml)) { printf("srf_read_xml failed for %s\n", srf_name); return -1; } break; case SRFB_TRACE_HEADER: printf("Found trace header at %zd\n", pos); if (0 != srf_read_trace_hdr(srf, &srf->th)) { printf("srf_read_trace_header failed for %s\n", srf_name); return -1; } if (0 != check_trace_header(opts, srf, &seen)) { printf("Bad trace header found in %s\n", srf_name); return -1; } break; case SRFB_TRACE_BODY: if (opts->verbosity > 0) { printf("Found trace body at %zd\n", pos); } if (0 != srf_read_trace_body(srf, &srf->tb, 0)) { printf("srf_read_trace_body failed for %s\n", srf_name); return -1; } if (0 != check_trace_body(opts, &trc, srf)) { printf("Bad trace body found in %s\n", srf_name); return -1; } if (srf->tb.trace) { free(srf->tb.trace); srf->tb.trace = NULL; } break; case SRFB_INDEX: if (0 != srf_read_index_hdr(srf, &srf->hdr, 1)) { printf("srf_read_index_hdr failed for %s\n", srf_name); return -1; } /* Skip the index body */ if (0 != fseeko(srf->fp, pos + srf->hdr.size, SEEK_SET)) { printf("Couldn't fseeko() on %s: %s\n", srf_name, strerror(errno)); return -1; } break; case SRFB_NULL_INDEX: { uint64_t idx = 0; printf("Found null index at %zd\n", pos); if (1 != fread(&idx, 8, 1, srf->fp)) { printf("Couldn't read null index from %s: %s\n", srf_name, strerror(errno)); return -1; } if (0 != idx) { printf("Null index does not contain zeros in %s\n", srf_name); } break; } default: printf("Block of unknown type '%d' found in %s\n\n", type, srf_name); return -1; } } while (1); }
/* * Looks for a trace name in an SRF archive and returns the binary contents * if found, or NULL if not. */ mFILE *find_reading(srf_t *srf, char *tr_name) { do { int type; switch(type = srf_next_block_type(srf)) { case -1: /* EOF */ return NULL; case SRFB_CONTAINER: if (0 != srf_read_cont_hdr(srf, &srf->ch)) return NULL; break; case SRFB_XML: if (0 != srf_read_xml(srf, &srf->xml)) return NULL; break; case SRFB_TRACE_HEADER: { /* off_t pos = ftell(srf->fp); */ if (0 != srf_read_trace_hdr(srf, &srf->th)) return NULL; #if 0 /* * If the name prefix doesn't match tr_name then skip this entire * block. */ if (0 != strncmp(tr_name, srf->th.id_prefix, strlen(srf->th.id_prefix)) && 0 != srf->th.next_block_offset) { fseek(srf->fp, pos + srf->th.next_block_offset, SEEK_SET); } #endif break; } case SRFB_TRACE_BODY: { mFILE *mf = mfcreate(NULL, 0); srf_trace_body_t tb; char name[512]; if (!mf || 0 != srf_read_trace_body(srf, &tb, 0)) return NULL; sprintf(name, "%s%s", srf->th.id_prefix, tb.read_id); if (strcmp(name, tr_name)) { mfdestroy(mf); if (tb.trace) free(tb.trace); continue; } if (srf->th.trace_hdr_size) mfwrite(srf->th.trace_hdr, 1, srf->th.trace_hdr_size, mf); if (tb.trace_size) mfwrite(tb.trace, 1, tb.trace_size, mf); if (tb.trace) free(tb.trace); mrewind(mf); return mf; } case SRFB_INDEX: { off_t pos = ftello(srf->fp); srf_read_index_hdr(srf, &srf->hdr, 1); /* Skip the index body */ fseeko(srf->fp, pos + srf->hdr.size, SEEK_SET); break; } case SRFB_NULL_INDEX: break; default: fprintf(stderr, "Block of unknown type '%c'. Aborting\n", type); return NULL; } } while (1); return NULL; }
/* * Given the archive name and the level_mode * generate information about the archive * * Note the generated srf file is NOT indexed * * Returns 0 on success. */ int srf_info(char *input, int level_mode, long *read_count, long *chunk_count, uint64_t *chunk_size, long key_count[NCHUNKS][NKEYS], long type_count[NCHUNKS][NTYPES], HashTable *regn_hash, uint64_t *base_count) { srf_t *srf; off_t pos; int type; int count = 0; long trace_body_count = 0; char name[1024]; if (NULL == (srf = srf_open(input, "rb"))) { perror(input); return 1; } while ((type = srf_next_block_type(srf)) >= 0) { switch (type) { case SRFB_CONTAINER: if( trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); trace_body_count = 0; } if (0 != srf_read_cont_hdr(srf, &srf->ch)) { fprintf(stderr, "Error reading container header.\nExiting.\n"); exit(1); } break; case SRFB_XML: if( trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); trace_body_count = 0; } if (0 != srf_read_xml(srf, &srf->xml)) { fprintf(stderr, "Error reading XML.\nExiting.\n"); exit(1); } break; case SRFB_TRACE_HEADER: if( trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); trace_body_count = 0; } if (0 != srf_read_trace_hdr(srf, &srf->th)) { fprintf(stderr, "Error reading trace header.\nExiting.\n"); exit(1); } if( 0 == (level_mode & (LEVEL_CHUNK | LEVEL_BASE)) ) break; /* Decode ZTR chunks in the header */ if (srf->mf) mfdestroy(srf->mf); srf->mf = mfcreate(NULL, 0); if (srf->th.trace_hdr_size) mfwrite(srf->th.trace_hdr, 1, srf->th.trace_hdr_size, srf->mf); if (srf->ztr) delete_ztr(srf->ztr); mrewind(srf->mf); if (NULL != (srf->ztr = partial_decode_ztr(srf, srf->mf, NULL))) { srf->mf_pos = mftell(srf->mf); } else { /* Maybe not enough to decode or no headerBlob. */ /* So delay until decoding the body. */ srf->mf_pos = 0; } mfseek(srf->mf, 0, SEEK_END); srf->mf_end = mftell(srf->mf); break; case SRFB_TRACE_BODY: { srf_trace_body_t old_tb; ztr_t *ztr_tmp; int no_trace = (level_mode & (LEVEL_CHUNK | LEVEL_BASE) ? 0 : 1); if (0 != srf_read_trace_body(srf, &old_tb, no_trace)) { fprintf(stderr, "Error reading trace body.\nExiting.\n"); exit(1); } if (-1 == construct_trace_name(srf->th.id_prefix, (unsigned char *)old_tb.read_id, old_tb.read_id_length, name, 512)) { fprintf(stderr, "Error constructing trace name.\nExiting.\n"); exit(1); } trace_body_count++; if( 1 == trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( "trace_name: %s + %s", srf->th.id_prefix, name+strlen(srf->th.id_prefix)); } read_count[READ_TOTAL]++; if (old_tb.flags & SRF_READ_FLAG_BAD_MASK ){ read_count[READ_BAD]++; } else { read_count[READ_GOOD]++; } if( 0 == (level_mode & (LEVEL_CHUNK | LEVEL_BASE)) ) break; if (!srf->mf) { fprintf(stderr, "Error reading trace body.\nExiting.\n"); exit(1); } mfseek(srf->mf, srf->mf_end, SEEK_SET); if (old_tb.trace_size) { mfwrite(old_tb.trace, 1, old_tb.trace_size, srf->mf); free(old_tb.trace); old_tb.trace = NULL; } mftruncate(srf->mf, mftell(srf->mf)); mfseek(srf->mf, srf->mf_pos, SEEK_SET); if (srf->ztr) ztr_tmp = ztr_dup(srf->ztr); /* inefficient, but simple */ else ztr_tmp = NULL; if ((ztr_tmp = partial_decode_ztr(srf, srf->mf, ztr_tmp))) { int i; for (i=0; i<ztr_tmp->nchunks; i++) { int ichunk = -1; switch (ztr_tmp->chunk[i].type) { case ZTR_TYPE_BASE: ichunk = CHUNK_BASE; chunk_size[ichunk] += ztr_tmp->chunk[i].dlength; if( parse_base(ztr_tmp, &ztr_tmp->chunk[i], base_count) ){ delete_ztr(ztr_tmp); return 1; } break; case ZTR_TYPE_CNF1: ichunk = CHUNK_CNF1; chunk_size[ichunk] += ztr_tmp->chunk[i].dlength; break; case ZTR_TYPE_CNF4: ichunk = CHUNK_CNF4; chunk_size[ichunk] += ztr_tmp->chunk[i].dlength; break; case ZTR_TYPE_SAMP: ichunk = CHUNK_SAMP; chunk_size[ichunk] += ztr_tmp->chunk[i].dlength; break; case ZTR_TYPE_SMP4: ichunk = CHUNK_SMP4; chunk_size[ichunk] += ztr_tmp->chunk[i].dlength; break; case ZTR_TYPE_REGN: ichunk = CHUNK_REGN; chunk_size[ichunk] += ztr_tmp->chunk[i].dlength; if( NULL == parse_regn(ztr_tmp, &ztr_tmp->chunk[i], regn_hash) ){ delete_ztr(ztr_tmp); return 1; } break; default: break; } if( ichunk > -1 ) { chunk_count[ichunk]++; count_mdata_keys(ztr_tmp, &ztr_tmp->chunk[i], ichunk, key_count, type_count); } } } if( ztr_tmp ) delete_ztr(ztr_tmp); count++; if( (level_mode == LEVEL_CHECK) && (count == 10) ){ printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); srf_destroy(srf, 1); return 0; } break; } case SRFB_INDEX: { off_t pos = ftell(srf->fp); if( trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); trace_body_count = 0; } printf( "Reading srf index block\n"); if (0 != srf_read_index_hdr(srf, &srf->hdr, 1)) { srf_destroy(srf, 1); fprintf(stderr, "Error reading srf index block header.\nExiting.\n"); exit(1); } /* Skip the index body */ fseeko(srf->fp, pos + srf->hdr.size, SEEK_SET); break; } case SRFB_NULL_INDEX: { uint64_t ilen; if( trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); trace_body_count = 0; } printf( "Reading srf null index block\n"); /* * Maybe the last 8 bytes of a the file (or previously was * last 8 bytes prior to concatenating SRF files together). * If so it's the index length and should always be 8 zeros. */ if (1 != fread(&ilen, 8, 1, srf->fp)) { srf_destroy(srf, 1); fprintf(stderr, "Error reading srf null index block.\nExiting.\n"); exit(1); } if (ilen != 0) { srf_destroy(srf, 1); fprintf(stderr, "Invalid srf null index block.\nExiting.\n"); exit(1); } break; } default: srf_destroy(srf, 1); fprintf(stderr, "Block of unknown type '%c'\nExiting.\n", type); exit(1); } } if( trace_body_count ){ if( level_mode & LEVEL_NAME ) printf( " ... %s x%ld\n", name+strlen(srf->th.id_prefix), trace_body_count); trace_body_count = 0; } /* the type should be -1 (EOF) */ if( type != -1 ) { fprintf(stderr, "Block of unknown type '%c'\nExiting.\n", type); exit(1); } /* are we really at the end of the srf file */ pos = ftell(srf->fp); fseek(srf->fp, 0, SEEK_END); if( pos != ftell(srf->fp) ){ fprintf(stderr, "srf file is corrupt\n"); exit(1); } srf_destroy(srf, 1); return 0; }