Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
0
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;
}
Exemple #4
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;
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
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);
}
Exemple #9
0
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;
}
Exemple #10
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);
}
Exemple #12
0
/*
 * 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);
	}
Exemple #13
0
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");
}
Exemple #14
0
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;
}