void *probe_worker_runfn(void *arg) { probe_pwpair_t *pair = (probe_pwpair_t *)arg; SEXP_t *probe_res, *obj, *oid; int probe_ret; #if defined(HAVE_PTHREAD_SETNAME_NP) pthread_setname_np(pthread_self(), "probe_worker"); #endif dD("handling SEAP message ID %u", pair->pth->sid); // probe_ret = -1; probe_res = pair->pth->msg_handler(pair->probe, pair->pth->msg, &probe_ret); // dD("handler result = %p, return code = %d", probe_res, probe_ret); /* Assuming that the red-black tree API is doing locking for us... */ if (rbt_i32_del(pair->probe->workers, pair->pth->sid, NULL) != 0) { dW("thread not found in the probe thread tree, probably canceled by an external signal"); /* * XXX: this is a possible deadlock; we can't send anything from * here because the signal handler replied to the message */ arg = NULL; SEAP_msg_free(pair->pth->msg); SEXP_free(probe_res); oscap_free(pair); return (NULL); } else { SEXP_t *items; dD("probe thread deleted"); obj = SEAP_msg_get(pair->pth->msg); oid = probe_obj_getattrval(obj, "id"); items = probe_cobj_get_items(probe_res); if (items != NULL) { SEXP_list_sort(items, SEXP_refcmp); SEXP_free(items); } if (probe_rcache_sexp_add(pair->probe->rcache, oid, probe_res) != 0) { /* TODO */ abort(); } SEXP_vfree(obj, oid, NULL); } if (probe_ret != 0) { /* * Something bad happened. A hint of the cause is stored as a error code in * probe_ret (should be). We'll send it to the library using a SEAP error packet. */ if (SEAP_replyerr(pair->probe->SEAP_ctx, pair->probe->sd, pair->pth->msg, probe_ret) == -1) { int ret = errno; dE("An error ocured while sending error status. errno=%u, %s.", errno, strerror(errno)); SEXP_free(probe_res); /* FIXME */ exit(ret); } SEXP_free(probe_res); } else { SEAP_msg_t *seap_reply; /* * OK, the probe actually returned something, let's send it to the library. */ seap_reply = SEAP_msg_new(); SEAP_msg_set(seap_reply, probe_res); if (SEAP_reply(pair->probe->SEAP_ctx, pair->probe->sd, seap_reply, pair->pth->msg) == -1) { int ret = errno; SEAP_msg_free(seap_reply); SEXP_free(probe_res); exit(ret); } SEAP_msg_free(seap_reply); SEXP_free(probe_res); } SEAP_msg_free(pair->pth->msg); oscap_free(pair->pth); oscap_free(pair); pthread_detach(pthread_self()); return (NULL); }
static struct oval_sysent *oval_sexp_to_sysent(struct oval_syschar_model *model, struct oval_sysitem *item, SEXP_t * sexp, struct oval_string_map *mask_map) { char *key; oval_syschar_status_t status; oval_datatype_t dt; struct oval_sysent *ent; key = probe_ent_getname(sexp); if (!key) return NULL; if (strcmp("message", key) == 0 && item != NULL) { struct oval_message *msg; oval_message_level_t lvl; SEXP_t *lvl_sexp, *txt_sexp; char txt[1024]; lvl_sexp = probe_obj_getattrval(sexp, "level"); lvl = SEXP_number_getu_32(lvl_sexp); txt_sexp = probe_ent_getval(sexp); SEXP_string_cstr_r(txt_sexp, txt, sizeof txt); SEXP_vfree(lvl_sexp, txt_sexp); /* TODO: sanity checks */ msg = oval_message_new(); oval_message_set_level(msg, lvl); oval_message_set_text(msg, txt); oval_sysitem_add_message(item, msg); return (NULL); } status = probe_ent_getstatus(sexp); dt = probe_ent_getdatatype(sexp); ent = oval_sysent_new(model); oval_sysent_set_name(ent, key); oval_sysent_set_status(ent, status); oval_sysent_set_datatype(ent, dt); if (mask_map == NULL || oval_string_map_get_value(mask_map, key) == NULL) oval_sysent_set_mask(ent, 0); else oval_sysent_set_mask(ent, 1); if (status != SYSCHAR_STATUS_EXISTS) return ent; if (dt == OVAL_DATATYPE_RECORD) { SEXP_t *srf, *srfs; probe_ent_getvals(sexp, &srfs); SEXP_list_foreach(srf, srfs) { struct oval_record_field *rf; rf = oval_record_field_ITEM_from_sexp(srf); oval_sysent_add_record_field(ent, rf); } SEXP_free(srfs); } else {