uint8_t* cli_bcapi_malloc(struct cli_bc_ctx *ctx, uint32_t size) { void *v; #if USE_MPOOL if (!ctx->mpool) { ctx->mpool = mpool_create(); if (!ctx->mpool) { cli_dbgmsg("bytecode: mpool_create failed!\n"); cli_event_error_oom(EV, 0); return NULL; } } v = mpool_malloc(ctx->mpool, size); #else /* TODO: implement using a list of pointers we allocated! */ cli_errmsg("cli_bcapi_malloc not implemented for systems without mmap yet!\n"); v = cli_malloc(size); #endif if (!v) cli_event_error_oom(EV, size); return v; }
int32_t cli_bcapi_hashset_new(struct cli_bc_ctx *ctx ) { unsigned n = ctx->nhashsets+1; struct cli_hashset *s = cli_realloc(ctx->hashsets, sizeof(*ctx->hashsets)*n); if (!s) { cli_event_error_oom(EV, 0); return -1; } ctx->hashsets = s; ctx->nhashsets = n; s = &s[n-1]; cli_hashset_init(s, 16, 80); return n-1; }
static inline void ev_chain(cli_events_t *ctx, struct cli_event *ev, union ev_val *val) { union ev_val *chain; uint32_t siz = sizeof(*chain) * (ev->count + 1); chain = cli_realloc(ev->u.v_chain, siz); if (!chain) { cli_event_error_oom(ctx, siz); return; } ev->u.v_chain = chain; ev->u.v_chain[ev->count] = *val; ev->count++; }
void cli_event_data(cli_events_t *ctx, unsigned id, const void *data, uint32_t len) { struct cli_event *ev = get_event(ctx, id); if (!ev) return; if (ev->type != ev_data) { cli_event_error_str(ctx, "cli_event_string must be called with ev_data type"); return; } switch (ev->multiple) { case multiple_last: { void *v_data = cli_realloc2(ev->u.v_data, len); if (v_data) { ev->u.v_data = v_data; memcpy(v_data, data, len); ev->count = len; } else { cli_event_error_oom(ctx, len); } break; } case multiple_concat: { void *v_data = cli_realloc2(ev->u.v_data, ev->count + len); if (v_data) { ev->u.v_data = v_data; memcpy((char*)v_data + ev->count, data, len); ev->count += len; } else { cli_event_error_oom(ctx, ev->count + len); } break; } } }
/* TODO: field in ctx, id of last bytecode that called magicscandesc, reset * after hooks/other bytecodes are run. TODO: need a more generic solution * to avoid uselessly recursing on bytecode-unpacked files, but also a way to * override the limit if we need it in a special situation */ int32_t cli_bcapi_write(struct cli_bc_ctx *ctx, uint8_t*data, int32_t len) { char err[128]; int32_t res; cli_ctx *cctx = (cli_ctx*)ctx->ctx; if (len < 0) { cli_warnmsg("Bytecode API: called with negative length!\n"); API_MISUSE(); return -1; } if (!ctx->outfd) { ctx->tempfile = cli_gentemp(cctx ? cctx->engine->tmpdir : NULL); if (!ctx->tempfile) { cli_dbgmsg("Bytecode API: Unable to allocate memory for tempfile\n"); cli_event_error_oom(EV, 0); return -1; } ctx->outfd = open(ctx->tempfile, O_RDWR|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); if (ctx->outfd == -1) { ctx->outfd = 0; cli_warnmsg("Bytecode API: Can't create file %s: %s\n", ctx->tempfile, cli_strerror(errno, err, sizeof(err))); cli_event_error_str(EV, "cli_bcapi_write: Can't create temporary file"); free(ctx->tempfile); return -1; } cli_dbgmsg("bytecode opened new tempfile: %s\n", ctx->tempfile); } cli_event_fastdata(ctx->bc_events, BCEV_WRITE, data, len); if (cli_checklimits("bytecode api", cctx, ctx->written + len, 0, 0)) return -1; res = cli_writen(ctx->outfd, data, len); if (res > 0) ctx->written += res; if (res == -1) { cli_warnmsg("Bytecode API: write failed: %s\n", cli_strerror(errno, err, sizeof(err))); cli_event_error_str(EV, "cli_bcapi_write: write failed"); } return res; }