void cli_pcre_perf_print() { struct sigperf_elem stats[MAX_TRACKED_PCRE], *elem = stats; int i, elems = 0, max_name_len = 0, name_len; if (!p_sigid || !p_sigevents) { cli_warnmsg("cli_pcre_perf_print: statistics requested but no PCREs were loaded!\n"); return; } memset(stats, 0, sizeof(stats)); for (i=0;i<MAX_TRACKED_PCRE;i++) { union ev_val val; uint32_t count; const char * name = cli_event_get_name(p_sigevents, i*PCRE_EVENTS_PER_SIG); cli_event_get(p_sigevents, i*PCRE_EVENTS_PER_SIG, &val, &count); if (!count) { if (name) cli_dbgmsg("No event triggered for %s\n", name); continue; } if (name) name_len = strlen(name); else name_len = 0; if (name_len > max_name_len) max_name_len = name_len; elem->name = name?name:"\"noname\""; elem->usecs = val.v_int; elem->run_count = count; cli_event_get(p_sigevents, i*PCRE_EVENTS_PER_SIG+1, &val, &count); elem->match_count = count; elem++; elems++; } if (max_name_len < strlen("PCRE Expression")) max_name_len = strlen("PCRE Expression"); cli_qsort(stats, elems, sizeof(struct sigperf_elem), sigelem_comp); elem = stats; /* name runs matches microsecs avg */ cli_infomsg (NULL, "%-*s %*s %*s %*s %*s\n", max_name_len, "PCRE Expression", 8, "#runs", 8, "#matches", 12, "usecs total", 9, "usecs avg"); cli_infomsg (NULL, "%-*s %*s %*s %*s %*s\n", max_name_len, "===============", 8, "=====", 8, "========", 12, "===========", 9, "========="); while (elem->run_count) { cli_infomsg (NULL, "%-*s %*lu %*lu %*llu %*.2f\n", max_name_len, elem->name, 8, elem->run_count, 8, elem->match_count, 12, (long long unsigned)elem->usecs, 9, (double)elem->usecs/elem->run_count); elem++; } }
int cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *data, const struct cli_target_info *info) { int ret; unsigned int i; struct cli_bm_patt *patt; if(!root->bm_patterns) { data->offtab = data->offset = NULL; data->cnt = data->pos = 0; return CL_SUCCESS; } data->cnt = data->pos = 0; data->offtab = (uint32_t *) cli_malloc(root->bm_patterns * sizeof(uint32_t)); if(!data->offtab) { cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offtab\n"); return CL_EMEM; } data->offset = (uint32_t *) cli_malloc(root->bm_patterns * sizeof(uint32_t)); if(!data->offset) { cli_errmsg("cli_bm_initoff: Can't allocate memory for data->offset\n"); free(data->offtab); return CL_EMEM; } for(i = 0; i < root->bm_patterns; i++) { patt = root->bm_pattab[i]; if(patt->offdata[0] == CLI_OFF_ABSOLUTE) { data->offtab[data->cnt] = patt->offset_min + patt->prefix_length; if(data->offtab[data->cnt] >= info->fsize) continue; data->cnt++; } else if((ret = cli_caloff(NULL, info, root->type, patt->offdata, &data->offset[patt->offset_min], NULL))) { cli_errmsg("cli_bm_initoff: Can't calculate relative offset in signature for %s\n", patt->virname); free(data->offtab); free(data->offset); return ret; } else if((data->offset[patt->offset_min] != CLI_OFF_NONE) && (data->offset[patt->offset_min] + patt->length <= info->fsize)) { if(!data->cnt || (data->offset[patt->offset_min] + patt->prefix_length != data->offtab[data->cnt - 1])) { data->offtab[data->cnt] = data->offset[patt->offset_min] + patt->prefix_length; if(data->offtab[data->cnt] >= info->fsize) continue; data->cnt++; } } } cli_qsort(data->offtab, data->cnt, sizeof(uint32_t), NULL); return CL_SUCCESS; }
/* Given mish data, reconstruct the partition details */ static int dmg_handle_mish(cli_ctx *ctx, unsigned int mishblocknum, char *dir, uint64_t xmlOffset, struct dmg_mish_with_stripes *mish_set) { struct dmg_block_data *blocklist = mish_set->stripes; uint64_t totalSectors = 0; uint32_t i; unsigned long projected_size; int ret = CL_CLEAN, ofd; uint8_t sorted = 1, writeable_data = 0; char outfile[NAME_MAX + 1]; /* First loop, fix endian-ness and check if already sorted */ for (i = 0; i < mish_set->mish->blockDataCount; i++) { blocklist[i].type = be32_to_host(blocklist[i].type); // blocklist[i].reserved = be32_to_host(blocklist[i].reserved); blocklist[i].startSector = be64_to_host(blocklist[i].startSector); blocklist[i].sectorCount = be64_to_host(blocklist[i].sectorCount); blocklist[i].dataOffset = be64_to_host(blocklist[i].dataOffset); blocklist[i].dataLength = be64_to_host(blocklist[i].dataLength); cli_dbgmsg("mish %u stripe " STDu32 " type " STDx32 " start " STDu64 " count " STDu64 " source " STDu64 " length " STDu64 "\n", mishblocknum, i, blocklist[i].type, blocklist[i].startSector, blocklist[i].sectorCount, blocklist[i].dataOffset, blocklist[i].dataLength); if ((blocklist[i].dataOffset > xmlOffset) || (blocklist[i].dataOffset + blocklist[i].dataLength > xmlOffset)) { cli_dbgmsg("dmg_handle_mish: invalid stripe offset and/or length\n"); return CL_EFORMAT; } if ((i > 0) && sorted && (blocklist[i].startSector < blocklist[i-1].startSector)) { cli_dbgmsg("dmg_handle_mish: stripes not in order, will have to sort\n"); sorted = 0; } if (dmg_track_sectors(&totalSectors, &writeable_data, i, blocklist[i].type, blocklist[i].sectorCount)) { /* reason was logged from dmg_track_sector_count */ return CL_EFORMAT; } } if (!sorted) { cli_qsort(blocklist, mish_set->mish->blockDataCount, sizeof(struct dmg_block_data), cmp_mish_stripes); } cli_dbgmsg("dmg_handle_mish: stripes in order!\n"); /* Size checks */ if ((writeable_data == 0) || (totalSectors == 0)) { cli_dbgmsg("dmg_handle_mish: no data to output\n"); return CL_CLEAN; } else if (totalSectors > (ULONG_MAX / DMG_SECTOR_SIZE)) { /* cli_checklimits only takes unsigned long for now */ cli_warnmsg("dmg_handle_mish: mish block %u too big to handle (for now)", mishblocknum); return CL_CLEAN; } projected_size = (unsigned long)(totalSectors * DMG_SECTOR_SIZE); ret = cli_checklimits("cli_scandmg", ctx, projected_size, 0, 0); if (ret != CL_CLEAN) { /* limits exceeded */ cli_dbgmsg("dmg_handle_mish: skipping block %u, limits exceeded\n", mishblocknum); return ret; } /* Prepare for file */ snprintf(outfile, sizeof(outfile)-1, "%s"PATHSEP"dmg%02u", dir, mishblocknum); outfile[sizeof(outfile)-1] = '\0'; ofd = open(outfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); if (ofd < 0) { char err[128]; cli_errmsg("cli_scandmg: Can't create temporary file %s: %s\n", outfile, cli_strerror(errno, err, sizeof(err))); return CL_ETMPFILE; } cli_dbgmsg("dmg_handle_mish: extracting block %u to %s\n", mishblocknum, outfile); /* Push data, stripe by stripe */ for(i=0; i < mish_set->mish->blockDataCount && ret == CL_CLEAN; i++) { switch (blocklist[i].type) { case DMG_STRIPE_EMPTY: case DMG_STRIPE_ZEROES: ret = dmg_stripe_zeroes(ctx, ofd, i, mish_set); break; case DMG_STRIPE_STORED: ret = dmg_stripe_store(ctx, ofd, i, mish_set); break; case DMG_STRIPE_ADC: ret = dmg_stripe_adc(ctx, ofd, i, mish_set); break; case DMG_STRIPE_DEFLATE: ret = dmg_stripe_inflate(ctx, ofd, i, mish_set); break; case DMG_STRIPE_BZ: ret = dmg_stripe_bzip(ctx, ofd, i, mish_set); break; case DMG_STRIPE_SKIP: case DMG_STRIPE_END: default: cli_dbgmsg("dmg_handle_mish: stripe " STDu32 ", skipped\n", i); break; } } /* If okay so far, scan rebuilt partition */ if (ret == CL_CLEAN) { ret = cli_partition_scandesc(ofd, ctx); } close(ofd); if (!ctx->engine->keeptmp) if (cli_unlink(outfile)) return CL_EUNLINK; return ret; }