static int adm_builtin(struct udev *udev, int argc, char *argv[])
{
	static const struct option options[] = {
		{ "help", no_argument, NULL, 'h' },
		{}
	};
	char *command = NULL;
	char *syspath = NULL;
	char filename[UTIL_PATH_SIZE];
	struct udev_device *dev = NULL;
	enum udev_builtin_cmd cmd;
	int rc = EXIT_SUCCESS;

	dbg(udev, "version %s\n", VERSION);

	for (;;) {
		int option;

		option = getopt_long(argc, argv, "h", options, NULL);
		if (option == -1)
			break;

		switch (option) {
		case 'h':
			help(udev);
			goto out;
		}
	}
	command = argv[optind++];
	if (command == NULL) {
		fprintf(stderr, "command missing\n");
		help(udev);
		rc = 2;
		goto out;
	}

	syspath = argv[optind++];
	if (syspath == NULL) {
		fprintf(stderr, "syspath missing\n\n");
		rc = 3;
		goto out;
	}

	/* add /sys if needed */
	if (strncmp(syspath, udev_get_sys_path(udev), strlen(udev_get_sys_path(udev))) != 0)
		util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), syspath, NULL);
	else
		util_strscpy(filename, sizeof(filename), syspath);
	util_remove_trailing_chars(filename, '/');

	dev = udev_device_new_from_syspath(udev, filename);
	if (dev == NULL) {
		fprintf(stderr, "unable to open device '%s'\n\n", filename);
		rc = 4;
		goto out;
	}

	cmd = udev_builtin_lookup(command);
	if (cmd >= UDEV_BUILTIN_MAX) {
		fprintf(stderr, "unknown command '%s'\n", command);
		help(udev);
		rc = 5;
		goto out;
	}

	if (udev_builtin_run(dev, cmd, true) < 0) {
		fprintf(stderr, "error executing '%s'\n\n", command);
		rc = 6;
	}
out:
	udev_device_unref(dev);
	return rc;
}
static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
        static const struct option options[] = {
                { "help", no_argument, NULL, 'h' },
                {}
        };
        char *command = NULL;
        char *syspath = NULL;
        char filename[UTIL_PATH_SIZE];
        struct udev_device *dev = NULL;
        enum udev_builtin_cmd cmd;
        int rc = EXIT_SUCCESS, c;

        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
                switch (c) {
                case 'h':
                        help(udev);
                        goto out;
                }

        command = argv[optind++];
        if (command == NULL) {
                fprintf(stderr, "command missing\n");
                help(udev);
                rc = 2;
                goto out;
        }

        syspath = argv[optind++];
        if (syspath == NULL) {
                fprintf(stderr, "syspath missing\n");
                rc = 3;
                goto out;
        }

        udev_builtin_init(udev);

        cmd = udev_builtin_lookup(command);
        if (cmd >= UDEV_BUILTIN_MAX) {
                fprintf(stderr, "unknown command '%s'\n", command);
                help(udev);
                rc = 5;
                goto out;
        }

        /* add /sys if needed */
        if (!startswith(syspath, "/sys"))
                strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
        else
                strscpy(filename, sizeof(filename), syspath);
        util_remove_trailing_chars(filename, '/');

        dev = udev_device_new_from_syspath(udev, filename);
        if (dev == NULL) {
                fprintf(stderr, "unable to open device '%s'\n\n", filename);
                rc = 4;
                goto out;
        }

        rc = udev_builtin_run(dev, cmd, command, true);
        if (rc < 0) {
                fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc);
                rc = 6;
        }
out:
        udev_device_unref(dev);
        udev_builtin_exit(udev);
        return rc;
}
Example #3
0
/**
 * udev_new:
 *
 * Create udev library context.
 *
 * The initial refcount is 1, and needs to be decremented to
 * release the resources of the udev library context.
 *
 * Returns: a new udev library context
 **/
struct udev *udev_new(void)
{
	struct udev *udev;
	const char *env;
	char *config_file;
	FILE *f;

	udev = calloc(1, sizeof(struct udev));
	if (udev == NULL)
		return NULL;
	udev->refcount = 1;
	udev->log_fn = log_stderr;
	udev->log_priority = LOG_ERR;
	udev_list_init(&udev->properties_list);
	udev->run = 1;
	udev->dev_path = strdup(UDEV_PREFIX "/dev");
	udev->sys_path = strdup("/sys");
	config_file = strdup(SYSCONFDIR "/udev/udev.conf");
	if (udev->dev_path == NULL ||
	    udev->sys_path == NULL ||
	    config_file == NULL)
		goto err;

	/* settings by environment and config file */
	env = getenv("SYSFS_PATH");
	if (env != NULL) {
		free(udev->sys_path);
		udev->sys_path = strdup(env);
		util_remove_trailing_chars(udev->sys_path, '/');
		udev_add_property(udev, "SYSFS_PATH", udev->sys_path);
	}

	env = getenv("UDEV_RUN");
	if (env != NULL && strcmp(env, "0") == 0)
		udev->run = 0;

	env = getenv("UDEV_CONFIG_FILE");
	if (env != NULL) {
		free(config_file);
		config_file = strdup(env);
		util_remove_trailing_chars(config_file, '/');
	}
	if (config_file == NULL)
		goto err;
	f = fopen(config_file, "r");
	if (f != NULL) {
		char line[UTIL_LINE_SIZE];
		int line_nr = 0;

		while (fgets(line, sizeof(line), f)) {
			size_t len;
			char *key;
			char *val;

			line_nr++;

			/* find key */
			key = line;
			while (isspace(key[0]))
				key++;

			/* comment or empty line */
			if (key[0] == '#' || key[0] == '\0')
				continue;

			/* split key/value */
			val = strchr(key, '=');
			if (val == NULL) {
				err(udev, "missing <key>=<value> in '%s'[%i], skip line\n", config_file, line_nr);
				continue;
			}
			val[0] = '\0';
			val++;

			/* find value */
			while (isspace(val[0]))
				val++;

			/* terminate key */
			len = strlen(key);
			if (len == 0)
				continue;
			while (isspace(key[len-1]))
				len--;
			key[len] = '\0';

			/* terminate value */
			len = strlen(val);
			if (len == 0)
				continue;
			while (isspace(val[len-1]))
				len--;
			val[len] = '\0';

			if (len == 0)
				continue;

			/* unquote */
			if (val[0] == '"' || val[0] == '\'') {
				if (val[len-1] != val[0]) {
					err(udev, "inconsistent quoting in '%s'[%i], skip line\n", config_file, line_nr);
					continue;
				}
				val[len-1] = '\0';
				val++;
			}

			if (strcasecmp(key, "udev_log") == 0) {
				udev_set_log_priority(udev, util_log_priority(val));
				continue;
			}
			if (strcasecmp(key, "udev_root") == 0) {
				free(udev->dev_path);
				udev->dev_path = strdup(val);
				util_remove_trailing_chars(udev->dev_path, '/');
				continue;
			}
			if (strcasecmp(key, "udev_rules") == 0) {
				free(udev->rules_path);
				udev->rules_path = strdup(val);
				util_remove_trailing_chars(udev->rules_path, '/');
				continue;
			}
		}
		fclose(f);
	}

	env = getenv("UDEV_ROOT");
	if (env != NULL) {
		free(udev->dev_path);
		udev->dev_path = strdup(env);
		util_remove_trailing_chars(udev->dev_path, '/');
		udev_add_property(udev, "UDEV_ROOT", udev->dev_path);
	}

	env = getenv("UDEV_LOG");
	if (env != NULL)
		udev_set_log_priority(udev, util_log_priority(env));

	if (udev->dev_path == NULL || udev->sys_path == NULL)
		goto err;
	dbg(udev, "context %p created\n", udev);
	dbg(udev, "log_priority=%d\n", udev->log_priority);
	dbg(udev, "config_file='%s'\n", config_file);
	dbg(udev, "dev_path='%s'\n", udev->dev_path);
	dbg(udev, "sys_path='%s'\n", udev->sys_path);
	if (udev->rules_path != NULL)
		dbg(udev, "rules_path='%s'\n", udev->rules_path);
	free(config_file);
	return udev;
err:
	free(config_file);
	err(udev, "context creation failed\n");
	udev_unref(udev);
	return NULL;
}