static void _npf_ruleset_transform1(prop_array_t rlset, prop_array_t rules) { prop_object_iterator_t it; prop_dictionary_t rldict; prop_array_t subrlset; it = prop_array_iterator(rules); while ((rldict = prop_object_iterator_next(it)) != NULL) { unsigned idx; /* Add rules to the array (reference is retained). */ prop_array_add(rlset, rldict); subrlset = prop_dictionary_get(rldict, "subrules"); if (subrlset) { /* Process subrules recursively. */ _npf_ruleset_transform1(rlset, subrlset); /* Add the skip-to position. */ idx = prop_array_count(rlset); prop_dictionary_set_uint32(rldict, "skip-to", idx); prop_dictionary_remove(rldict, "subrules"); } } prop_object_iterator_release(it); }
static bool _prop_array_internalize_continue(prop_stack_t stack, prop_object_t *obj, struct _prop_object_internalize_context *ctx, void *data, prop_object_t child) { prop_array_t array; _PROP_ASSERT(data == NULL); if (child == NULL) goto bad; /* Element could not be parsed. */ array = *obj; if (prop_array_add(array, child) == false) { prop_object_release(child); goto bad; } prop_object_release(child); /* * Current element is processed and added, look for next. */ return (_prop_array_internalize_body(stack, obj, ctx)); bad: prop_object_release(*obj); *obj = NULL; return (true); }
int npf_nat_insert(nl_config_t *ncf, nl_nat_t *nt, pri_t pri __unused) { prop_dictionary_t rldict = nt->nrl_dict; prop_dictionary_set_int32(rldict, "priority", NPF_PRI_LAST); prop_array_add(ncf->ncf_nat_list, rldict); return 0; }
int _npf_alg_load(nl_config_t *ncf, const char *name) { prop_dictionary_t al_dict; if (_npf_prop_array_lookup(ncf->ncf_alg_list, "name", name)) return EEXIST; al_dict = prop_dictionary_create(); prop_dictionary_set_cstring(al_dict, "name", name); prop_array_add(ncf->ncf_alg_list, al_dict); prop_object_release(al_dict); return 0; }
int npf_rproc_insert(nl_config_t *ncf, nl_rproc_t *rp) { prop_dictionary_t rpdict = rp->nrp_dict; const char *name; if (!prop_dictionary_get_cstring_nocopy(rpdict, "name", &name)) { return EINVAL; } if (npf_rproc_exists_p(ncf, name)) { return EEXIST; } prop_array_add(ncf->ncf_rproc_list, rpdict); return 0; }
int npf_rproc_extcall(nl_rproc_t *rp, nl_ext_t *ext) { prop_dictionary_t rpdict = rp->nrp_dict; prop_dictionary_t extdict = ext->nxt_dict; prop_array_t extcalls; extcalls = prop_dictionary_get(rpdict, "extcalls"); if (_npf_prop_array_lookup(extcalls, "name", ext->nxt_name)) { return EEXIST; } prop_dictionary_set_cstring(extdict, "name", ext->nxt_name); prop_array_add(extcalls, extdict); return 0; }
int npf_table_insert(nl_config_t *ncf, nl_table_t *tl) { prop_dictionary_t tldict = tl->ntl_dict; const char *name = NULL; if (!prop_dictionary_get_cstring_nocopy(tldict, "name", &name)) { return EINVAL; } if (_npf_table_exists_p(ncf, name)) { return EEXIST; } prop_array_add(ncf->ncf_table_list, tldict); return 0; }
void _npf_debug_addif(nl_config_t *ncf, const char *ifname) { prop_dictionary_t ifdict, dbg = _npf_debug_initonce(ncf); prop_array_t iflist = prop_dictionary_get(dbg, "interfaces"); u_int if_idx = if_nametoindex(ifname); if (_npf_prop_array_lookup(iflist, "name", ifname)) { return; } ifdict = prop_dictionary_create(); prop_dictionary_set_cstring(ifdict, "name", ifname); prop_dictionary_set_uint32(ifdict, "index", if_idx); prop_array_add(iflist, ifdict); prop_object_release(ifdict); }
int npf_rule_insert(nl_config_t *ncf, nl_rule_t *parent, nl_rule_t *rl) { prop_dictionary_t rldict = rl->nrl_dict; prop_array_t rlset; if (parent) { prop_dictionary_t pdict = parent->nrl_dict; rlset = prop_dictionary_get(pdict, "subrules"); if (rlset == NULL) { rlset = prop_array_create(); prop_dictionary_set(pdict, "subrules", rlset); prop_object_release(rlset); } } else { rlset = ncf->ncf_rules_list; } prop_array_add(rlset, rldict); return 0; }
int npf_table_add_entry(nl_table_t *tl, int af, const npf_addr_t *addr, const npf_netmask_t mask) { prop_dictionary_t tldict = tl->ntl_dict, entdict; prop_array_t tblents; prop_data_t addrdata; unsigned alen; /* Create the table entry. */ entdict = prop_dictionary_create(); if (entdict == NULL) { return ENOMEM; } switch (af) { case AF_INET: alen = sizeof(struct in_addr); break; case AF_INET6: alen = sizeof(struct in6_addr); break; default: return EINVAL; } addrdata = prop_data_create_data(addr, alen); prop_dictionary_set(entdict, "addr", addrdata); prop_dictionary_set_uint8(entdict, "mask", mask); prop_object_release(addrdata); tblents = prop_dictionary_get(tldict, "entries"); prop_array_add(tblents, entdict); prop_object_release(entdict); return 0; }
/* * Called back during autoconfiguration for each device found */ void device_register(device_t dev, void *aux) { device_t busdev = device_parent(dev); int ofnode = 0; /* * We don't know the type of 'aux' - it depends on the * bus this device attaches to. We are only interested in * certain bus types, this only is used to find the boot * device. */ if (busdev == NULL) { /* * Ignore mainbus0 itself, it certainly is not a boot * device. */ } else if (device_is_a(busdev, "mainbus")) { struct mainbus_attach_args *ma = aux; ofnode = ma->ma_node; } else if (device_is_a(busdev, "pci")) { struct pci_attach_args *pa = aux; ofnode = PCITAG_NODE(pa->pa_tag); } else if (device_is_a(busdev, "sbus") || device_is_a(busdev, "dma") || device_is_a(busdev, "ledma")) { struct sbus_attach_args *sa = aux; ofnode = sa->sa_node; } else if (device_is_a(busdev, "ebus")) { struct ebus_attach_args *ea = aux; ofnode = ea->ea_node; } else if (device_is_a(busdev, "iic")) { struct i2c_attach_args *ia = aux; if (ia->ia_name == NULL) /* indirect config */ return; ofnode = (int)ia->ia_cookie; } else if (device_is_a(dev, "sd") || device_is_a(dev, "cd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; int off = 0; /* * There are two "cd" attachments: * atapibus -> atabus -> controller * scsibus -> controller * We want the node of the controller. */ if (device_is_a(busdev, "atapibus")) { busdev = device_parent(busdev); /* * if the atapibus is connected to the secondary * channel of the atabus, we need an offset of 2 * to match OF's idea of the target number. * (i.e. on U5/U10 "cdrom" and "disk2" have the * same target encoding, though different names) */ if (periph->periph_channel->chan_channel == 1) off = 2; } ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, periph->periph_target + off, 0, periph->periph_lun); return; } else if (device_is_a(dev, "wd")) { struct ata_device *adev = aux; ofnode = device_ofnode(device_parent(busdev)); dev_path_drive_match(dev, ofnode, adev->adev_channel*2+ adev->adev_drv_data->drive, 0, 0); return; } if (busdev == NULL) return; if (ofnode != 0) { uint8_t eaddr[ETHER_ADDR_LEN]; char tmpstr[32]; char tmpstr2[32]; int node; uint32_t id = 0; uint64_t nwwn = 0, pwwn = 0; prop_dictionary_t dict; prop_data_t blob; prop_number_t pwwnd = NULL, nwwnd = NULL; prop_number_t idd = NULL; device_setofnode(dev, ofnode); dev_path_exact_match(dev, ofnode); if (OF_getprop(ofnode, "name", tmpstr, sizeof(tmpstr)) <= 0) tmpstr[0] = 0; if (OF_getprop(ofnode, "device_type", tmpstr2, sizeof(tmpstr2)) <= 0) tmpstr2[0] = 0; /* * If this is a network interface, note the * mac address. */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr, "ethernet") == 0 || strcmp(tmpstr2, "network") == 0 || strcmp(tmpstr2, "ethernet") == 0 || OF_getprop(ofnode, "mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN || OF_getprop(ofnode, "local-mac-address", &eaddr, sizeof(eaddr)) >= ETHER_ADDR_LEN) { dict = device_properties(dev); /* * Is it a network interface with FCode? */ if (strcmp(tmpstr, "network") == 0 || strcmp(tmpstr2, "network") == 0) { prop_dictionary_set_bool(dict, "without-seeprom", true); prom_getether(ofnode, eaddr); } else { if (!prom_get_node_ether(ofnode, eaddr)) goto noether; } blob = prop_data_create_data(eaddr, ETHER_ADDR_LEN); prop_dictionary_set(dict, "mac-address", blob); prop_object_release(blob); of_to_dataprop(dict, ofnode, "shared-pins", "shared-pins"); } noether: /* is this a FC node? */ if (strcmp(tmpstr, "scsi-fcp") == 0) { dict = device_properties(dev); if (OF_getprop(ofnode, "port-wwn", &pwwn, sizeof(pwwn)) == sizeof(pwwn)) { pwwnd = prop_number_create_unsigned_integer(pwwn); prop_dictionary_set(dict, "port-wwn", pwwnd); prop_object_release(pwwnd); } if (OF_getprop(ofnode, "node-wwn", &nwwn, sizeof(nwwn)) == sizeof(nwwn)) { nwwnd = prop_number_create_unsigned_integer(nwwn); prop_dictionary_set(dict, "node-wwn", nwwnd); prop_object_release(nwwnd); } } /* is this an spi device? look for scsi-initiator-id */ if (strcmp(tmpstr2, "scsi") == 0 || strcmp(tmpstr2, "scsi-2") == 0) { dict = device_properties(dev); for (node = ofnode; node != 0; node = OF_parent(node)) { if (OF_getprop(node, "scsi-initiator-id", &id, sizeof(id)) <= 0) continue; idd = prop_number_create_unsigned_integer(id); prop_dictionary_set(dict, "scsi-initiator-id", idd); prop_object_release(idd); break; } } } /* * Check for I2C busses and add data for their direct configuration. */ if (device_is_a(dev, "iic")) { int busnode = device_ofnode(busdev); if (busnode) { prop_dictionary_t props = device_properties(busdev); prop_object_t cfg = prop_dictionary_get(props, "i2c-child-devices"); if (!cfg) { int node; const char *name; /* * pmu's i2c devices are under the "i2c" node, * so find it out. */ name = prom_getpropstring(busnode, "name"); if (strcmp(name, "pmu") == 0) { for (node = OF_child(busnode); node != 0; node = OF_peer(node)) { name = prom_getpropstring(node, "name"); if (strcmp(name, "i2c") == 0) { busnode = node; break; } } } of_enter_i2c_devs(props, busnode, sizeof(cell_t)); } } /* * Add SPARCle spdmem devices (0x50 and 0x51) that the * firmware does not know about. */ if (!strcmp(machine_model, "TAD,SPARCLE")) { prop_dictionary_t props = device_properties(busdev); prop_array_t cfg = prop_array_create(); int i; DPRINTF(ACDB_PROBE, ("\nAdding spdmem for SPARCle ")); for (i = 0x50; i <= 0x51; i++) { prop_dictionary_t spd = prop_dictionary_create(); prop_dictionary_set_cstring(spd, "name", "dimm-spd"); prop_dictionary_set_uint32(spd, "addr", i); prop_dictionary_set_uint64(spd, "cookie", 0); prop_array_add(cfg, spd); prop_object_release(spd); } prop_dictionary_set(props, "i2c-child-devices", cfg); prop_object_release(cfg); } } /* set properties for PCI framebuffers */ if (device_is_a(busdev, "pci")) { /* see if this is going to be console */ struct pci_attach_args *pa = aux; prop_dictionary_t dict; int sub; int console = 0; dict = device_properties(dev); /* we only care about display devices from here on */ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY) return; console = (ofnode == console_node); if (!console) { /* * see if any child matches since OF attaches * nodes for each head and /chosen/stdout * points to the head rather than the device * itself in this case */ sub = OF_child(ofnode); while ((sub != 0) && (sub != console_node)) { sub = OF_peer(sub); } if (sub == console_node) { console = true; } } copyprops(busdev, ofnode, dict, console); if (console) { uint64_t cmap_cb; prop_dictionary_set_uint32(dict, "instance_handle", console_instance); gfb_cb.gcc_cookie = (void *)(intptr_t)console_instance; gfb_cb.gcc_set_mapreg = of_set_palette; cmap_cb = (uint64_t)(uintptr_t)&gfb_cb; prop_dictionary_set_uint64(dict, "cmap_callback", cmap_cb); } #ifdef notyet else { int width; /* * the idea is to 'open' display devices with no useful * properties, in the hope that the firmware will * properly initialize them and we can run things like * genfb on them */ if (OF_getprop(node, "width", &width, sizeof(width)) != 4) { instance = OF_open(name); #endif } } /* * Called back after autoconfiguration of a device is done */ void device_register_post_config(device_t dev, void *aux) { if (booted_device == NULL && device_is_a(dev, "sd")) { struct scsipibus_attach_args *sa = aux; struct scsipi_periph *periph = sa->sa_periph; uint64_t wwn = 0; int ofnode; /* * If this is a FC-AL drive it will have * aquired its WWN device property by now, * so we can properly match it. */ if (prop_dictionary_get_uint64(device_properties(dev), "port-wwn", &wwn)) { /* * Different to what we do in device_register, * we do not pass the "controller" ofnode, * because FC-AL devices attach below a "fp" node, * E.g.: /pci/SUNW,qlc@4/fp@0,0/disk * and we need the parent of "disk" here. */ ofnode = device_ofnode( device_parent(device_parent(dev))); for (ofnode = OF_child(ofnode); ofnode != 0 && booted_device == NULL; ofnode = OF_peer(ofnode)) { dev_path_drive_match(dev, ofnode, periph->periph_target, wwn, periph->periph_lun); } } } } static void copyprops(device_t busdev, int node, prop_dictionary_t dict, int is_console) { device_t cntrlr; prop_dictionary_t psycho; paddr_t fbpa, mem_base = 0; uint32_t temp, fboffset; uint32_t fbaddr = 0; int options; char output_device[256]; char *pos; cntrlr = device_parent(busdev); if (cntrlr != NULL) { psycho = device_properties(cntrlr); prop_dictionary_get_uint64(psycho, "mem_base", &mem_base); } if (is_console) prop_dictionary_set_bool(dict, "is_console", 1); of_to_uint32_prop(dict, node, "width", "width"); of_to_uint32_prop(dict, node, "height", "height"); of_to_uint32_prop(dict, node, "linebytes", "linebytes"); if (!of_to_uint32_prop(dict, node, "depth", "depth") && /* Some cards have an extra space in the property name */ !of_to_uint32_prop(dict, node, "depth ", "depth")) { /* * XXX we should check linebytes vs. width but those * FBs that don't have a depth property ( /chaos/control... ) * won't have linebytes either */ prop_dictionary_set_uint32(dict, "depth", 8); } OF_getprop(node, "address", &fbaddr, sizeof(fbaddr)); if (fbaddr != 0) { pmap_extract(pmap_kernel(), fbaddr, &fbpa); #ifdef DEBUG printf("membase: %lx fbpa: %lx\n", (unsigned long)mem_base, (unsigned long)fbpa); #endif if (mem_base == 0) { /* XXX this is guesswork */ fboffset = (uint32_t)(fbpa & 0xffffffff); } fboffset = (uint32_t)(fbpa - mem_base); prop_dictionary_set_uint32(dict, "address", fboffset); } if (!of_to_dataprop(dict, node, "EDID", "EDID")) of_to_dataprop(dict, node, "edid", "EDID"); temp = 0; if (OF_getprop(node, "ATY,RefCLK", &temp, sizeof(temp)) != 4) { OF_getprop(OF_parent(node), "ATY,RefCLK", &temp, sizeof(temp)); } if (temp != 0) prop_dictionary_set_uint32(dict, "refclk", temp / 10); /* * finally, let's see if there's a video mode specified in * output-device and pass it on so drivers like radeonfb * can do their thing */ if (!is_console) return; options = OF_finddevice("/options"); if ((options == 0) || (options == -1)) return; if (OF_getprop(options, "output-device", output_device, 256) == 0) return; /* find the mode string if there is one */ pos = strstr(output_device, ":r"); if (pos == NULL) return; prop_dictionary_set_cstring(dict, "videomode", pos + 2); } static void of_set_palette(void *cookie, int index, int r, int g, int b) { int ih = (int)((intptr_t)cookie); OF_call_method_1("color!", ih, 4, r, g, b, index); }
/* * Get description of all tables loaded to device from kernel * and send it to libdevmapper. * * Output dictionary for every table: * * <key>cmd_data</key> * <array> * <dict> * <key>type<key> * <string>...</string> * * <key>start</key> * <integer>...</integer> * * <key>length</key> * <integer>...</integer> * * <key>params</key> * <string>...</string> * </dict> * </array> * */ int dm_table_status_ioctl(prop_dictionary_t dm_dict) { dm_dev_t *dmv; dm_table_t *tbl; dm_table_entry_t *table_en; prop_array_t cmd_array; prop_dictionary_t target_dict; uint32_t rec_size, minor; const char *name, *uuid; char *params; int flags; int table_type; dmv = NULL; uuid = NULL; name = NULL; params = NULL; flags = 0; rec_size = 0; prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_NAME, &name); prop_dictionary_get_cstring_nocopy(dm_dict, DM_IOCTL_UUID, &uuid); prop_dictionary_get_uint32(dm_dict, DM_IOCTL_FLAGS, &flags); prop_dictionary_get_uint32(dm_dict, DM_IOCTL_MINOR, &minor); cmd_array = prop_array_create(); if ((dmv = dm_dev_lookup(name, uuid, minor)) == NULL) { DM_REMOVE_FLAG(flags, DM_EXISTS_FLAG); return ENOENT; } /* * if DM_QUERY_INACTIVE_TABLE_FLAG is passed we need to query * INACTIVE TABLE */ if (flags & DM_QUERY_INACTIVE_TABLE_FLAG) table_type = DM_TABLE_INACTIVE; else table_type = DM_TABLE_ACTIVE; if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_ACTIVE)) DM_ADD_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); else { DM_REMOVE_FLAG(flags, DM_ACTIVE_PRESENT_FLAG); if (dm_table_get_target_count(&dmv->table_head, DM_TABLE_INACTIVE)) DM_ADD_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); else { DM_REMOVE_FLAG(flags, DM_INACTIVE_PRESENT_FLAG); } } if (dmv->flags & DM_SUSPEND_FLAG) DM_ADD_FLAG(flags, DM_SUSPEND_FLAG); prop_dictionary_set_uint32(dm_dict, DM_IOCTL_MINOR, dmv->minor); aprint_debug("Status of device tables: %s--%d\n", name, dmv->table_head.cur_active_table); tbl = dm_table_get_entry(&dmv->table_head, table_type); SLIST_FOREACH(table_en, tbl, next) { target_dict = prop_dictionary_create(); aprint_debug("%016" PRIu64 ", length %016" PRIu64 ", target %s\n", table_en->start, table_en->length, table_en->target->name); prop_dictionary_set_uint64(target_dict, DM_TABLE_START, table_en->start); prop_dictionary_set_uint64(target_dict, DM_TABLE_LENGTH, table_en->length); prop_dictionary_set_cstring(target_dict, DM_TABLE_TYPE, table_en->target->name); /* dm_table_get_cur_actv.table ?? */ prop_dictionary_set_int32(target_dict, DM_TABLE_STAT, dmv->table_head.cur_active_table); if (flags & DM_STATUS_TABLE_FLAG) { params = table_en->target->status (table_en->target_config); if (params != NULL) { prop_dictionary_set_cstring(target_dict, DM_TABLE_PARAMS, params); kfree(params, M_DM); } } prop_array_add(cmd_array, target_dict); prop_object_release(target_dict); }
void testcase_entry_parser(void *arg, char **tokens) { prop_array_t runlist; prop_dictionary_t testcase_dict; struct testcase *testcase; char *options[256]; int i, r, nopts; runlist = (prop_array_t)arg; testcase = malloc(sizeof(struct testcase)); if (testcase == NULL) err(1, "could not malloc testcase memory"); bzero(testcase, sizeof(struct testcase)); entry_check_num_args(tokens, 3); testcase->argv = &tokens[3]; for (testcase->argc = 0; testcase->argv[testcase->argc] != NULL; testcase->argc++) ; nopts = parse_options(tokens[2], options); testcase->name = tokens[0]; if (strcmp(tokens[1], "userland") == 0) { testcase->type = TESTCASE_TYPE_USERLAND; } else if (strcmp(tokens[1], "kernel") == 0) { testcase->type = TESTCASE_TYPE_KERNEL; } else if (strcmp(tokens[1], "buildonly") == 0) { testcase->type = TESTCASE_TYPE_BUILDONLY; } else { syntax_error("Unknown type: %s", tokens[1]); /* NOTREACHED */ } testcase->type_str = tokens[1]; config_get_defaults(&testcase->opts); for (i = 0; i < nopts; i++) parse_testcase_option(&testcase->opts, options[i]); if ((testcase->type != TESTCASE_TYPE_USERLAND) && (testcase->opts.flags & (TESTCASE_INT_PRE | TESTCASE_INT_POST))) syntax_error("'intpre' and 'intpost' options are only valid " "with testcase type 'userland'"); if ((testcase->type == TESTCASE_TYPE_BUILDONLY) && (testcase->opts.flags & TESTCASE_NOBUILD)) syntax_error("'nobuild' option is incompatible with type " "'buildonly'"); testcase_dict = testcase_from_struct(testcase); if (testcase->opts.pre_cmd != NULL) free(testcase->opts.pre_cmd); if (testcase->opts.post_cmd != NULL) free(testcase->opts.post_cmd); if (testcase->opts.make_cmd != NULL) free(testcase->opts.make_cmd); free(testcase); r = prop_array_add(runlist, testcase_dict); if (r == 0) err(1, "prop_array_add failed"); }
void udev_read_event(int fd) { struct pdev_array_entry *pae; prop_dictionary_t dict, evdict, devdict; prop_number_t pn; prop_string_t ps; prop_object_t po; prop_array_t pa; char *xml; int n, idx, evtype; size_t sz; sz = 4096 * 1024; xml = malloc(sz); /* 4 MB */ again: if ((n = read(fd, xml, sz)) <= 0) { if (errno == ENOMEM) { sz <<= 2; if ((xml = realloc(xml, sz)) == NULL) { syslog(LOG_ERR, "could not realloc xml memory"); return; } goto again; } free(xml); return; } dict = prop_dictionary_internalize(xml); free(xml); if (dict == NULL) { syslog(LOG_ERR, "internalization of xml failed"); return; } pn = prop_dictionary_get(dict, "evtype"); if (pn == NULL) { syslog(LOG_ERR, "read_event: no key evtype"); goto out; } evtype = prop_number_integer_value(pn); evdict = prop_dictionary_get(dict, "evdict"); if (evdict == NULL) { syslog(LOG_ERR, "read_event: no key evdict"); goto out; } switch (evtype) { case UDEV_EVENT_ATTACH: monitor_queue_event(dict); pae = pdev_array_entry_get_last(); pa = prop_array_copy(pae->pdev_array); pdev_array_entry_unref(pae); if (pa == NULL) goto out; prop_array_add(pa, evdict); pdev_array_entry_insert(pa); break; case UDEV_EVENT_DETACH: monitor_queue_event(dict); if ((devdict = find_dev_dict(-1, evdict, &idx)) == NULL) goto out; pae = pdev_array_entry_get_last(); pa = prop_array_copy(pae->pdev_array); pdev_array_entry_unref(pae); if (pa == NULL) goto out; prop_array_remove(pa, idx); pdev_array_entry_insert(pa); break; case UDEV_EV_KEY_UPDATE: if ((devdict = find_dev_dict(-1, evdict, NULL)) == NULL) goto out; if ((ps = prop_dictionary_get(evdict, "key")) == NULL) goto out; if ((po = prop_dictionary_get(evdict, "value")) == NULL) goto out; /* prop_object_retain(po); */ /* not necessary afaik */ prop_dictionary_set(devdict, prop_string_cstring_nocopy(ps), po); break; case UDEV_EV_KEY_REMOVE: if ((devdict = find_dev_dict(-1, evdict, NULL)) == NULL) goto out; if ((ps = prop_dictionary_get(evdict, "key")) == NULL) goto out; prop_dictionary_remove(devdict, prop_string_cstring_nocopy(ps)); break; default: syslog(LOG_ERR, "read_event: unknown evtype %d", evtype); } out: prop_object_release(dict); return; }