示例#1
0
/**
 * sysfs_open_class: opens specific class and all its devices on system
 * returns sysfs_class structure with success or NULL with error.
 */
struct sysfs_class *sysfs_open_class(const char *name)
{
    struct sysfs_class *cls = NULL;
    char *c, classpath[SYSFS_PATH_MAX];

    if (!name) {
        errno = EINVAL;
        return NULL;
    }

    memset(classpath, 0, SYSFS_PATH_MAX);
    if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) {
        dprintf("Sysfs not supported on this system\n");
        return NULL;
    }

    safestrcat(classpath, "/");
    if (strcmp(name, SYSFS_BLOCK_NAME) == 0) {
        safestrcat(classpath, SYSFS_BLOCK_NAME);
        if (!sysfs_path_is_dir(classpath))
            goto done;
        c = strrchr(classpath, '/');
        *(c+1) = '\0';
    }
    safestrcat(classpath, SYSFS_CLASS_NAME);
    safestrcat(classpath, "/");
    safestrcat(classpath, name);
done:
    if (sysfs_path_is_dir(classpath)) {
        dprintf("Class %s not found on the system\n", name);
        return NULL;
    }

    cls = alloc_class();
    if (cls == NULL) {
        dprintf("calloc failed\n");
        return NULL;
    }
    safestrcpy(cls->name, name);
    safestrcpy(cls->path, classpath);
    if ((sysfs_remove_trailing_slash(cls->path)) != 0) {
        dprintf("Invalid path to class device %s\n", cls->path);
        sysfs_close_class(cls);
        return NULL;
    }

    return cls;
}
示例#2
0
/**
 * get_classdev_path: given the class and a device in the class, return the
 * 		absolute path to the device
 * @classname: name of the class
 * @clsdev: the class device
 * @path: buffer to return path
 * @psize: size of "path"
 * Returns 0 on SUCCESS or -1 on error
 */
static int get_classdev_path(const char *classname, const char *clsdev,
                             char *path, size_t len)
{
    char *c;

    if (!classname || !clsdev || !path) {
        errno = EINVAL;
        return -1;
    }
    if (sysfs_get_mnt_path(path, len) != 0) {
        dprintf("Error getting sysfs mount path\n");
        return -1;
    }
    safestrcatmax(path, "/", len);
    if (strncmp(classname, SYSFS_BLOCK_NAME,
                sizeof(SYSFS_BLOCK_NAME)) == 0) {
        safestrcatmax(path, SYSFS_BLOCK_NAME, len);
        if (!sysfs_path_is_dir(path))
            goto done;
        c = strrchr(path, '/');
        *(c+1) = '\0';
    }
    safestrcatmax(path, SYSFS_CLASS_NAME, len);
    safestrcatmax(path, "/", len);
    safestrcatmax(path, classname, len);
done:
    safestrcatmax(path, "/", len);
    safestrcatmax(path, clsdev, len);
    return 0;
}
示例#3
0
/* If /sys/class/net/XXX/bridge exists then it must be a bridge */
static int isbridge(const struct sysfs_class_device *dev)
{
    char path[SYSFS_PATH_MAX];

    snprintf(path, sizeof(path), "%s/bridge", dev->path);
    return !sysfs_path_is_dir(path);
}
示例#4
0
/**
 * read_dir_subdirs: grabs subdirs in a specific directory
 * @sysdir: sysfs directory to read
 * returns list of directory names with success and NULL with error.
 */
struct sysfs_device *sysfs_read_dir_subdirs(const char *path)
{
	DIR *dir = NULL;
	struct dirent *dirent = NULL;
	char file_path[SYSFS_PATH_MAX];
	struct sysfs_device *dev = NULL;

	if (!path) {
		errno = EINVAL;
		return NULL;
	}

	dev = sysfs_open_device_path(path);

	dir = opendir(path);
	if (!dir) {
		dprintf("Error opening directory %s\n", path);
		return NULL;
	}
	while ((dirent = readdir(dir)) != NULL) {
		if (0 == strcmp(dirent->d_name, "."))
			 continue;
		if (0 == strcmp(dirent->d_name, ".."))
			continue;
		memset(file_path, 0, SYSFS_PATH_MAX);
		safestrcpy(file_path, path);
		safestrcat(file_path, "/");
		safestrcat(file_path, dirent->d_name);
		if (!sysfs_path_is_dir(file_path))
			add_subdirectory(dev, file_path);
	}
	closedir(dir);
	return dev;
}
示例#5
0
/*
 * Get bridge parameters using either sysfs or old
 * ioctl.
 */
static int br_get_bridge_info(const char *bridge, struct bridge_info *info)
{
#ifdef HAVE_LIBSYSFS
	struct sysfs_class_device *dev;
	char path[SYSFS_PATH_MAX];

	if (!br_class_net)
		goto fallback;

	dev = sysfs_get_class_device(br_class_net, bridge);
	if (!dev) {
		dprintf("get_class_device '%s' failed\n", bridge);
		goto fallback;
	}

	snprintf(path, SYSFS_PATH_MAX, "%s/bridge", dev->path);
	if (sysfs_path_is_dir(path)) {
		dprintf("path '%s' is not a directory\n", path);
		sysfs_close_class_device(dev);
		goto fallback;
	}

	memset(info, 0, sizeof(*info));
	fetch_id(dev, BRIDGEATTR("root_id"), &info->designated_root);
	fetch_id(dev, BRIDGEATTR("bridge_id"), &info->bridge_id);
	info->root_path_cost = fetch_int(dev, BRIDGEATTR("root_path_cost"));
	fetch_tv(dev, BRIDGEATTR("max_age"), &info->max_age);
	fetch_tv(dev, BRIDGEATTR("hello_time"), &info->hello_time);
	fetch_tv(dev, BRIDGEATTR("forward_delay"), &info->forward_delay);
	fetch_tv(dev, BRIDGEATTR("max_age"), &info->bridge_max_age);
	fetch_tv(dev, BRIDGEATTR("hello_time"), &info->bridge_hello_time);
	fetch_tv(dev, BRIDGEATTR("forward_delay"), &info->bridge_forward_delay);
	fetch_tv(dev, BRIDGEATTR("ageing_time"), &info->ageing_time);
	fetch_tv(dev, BRIDGEATTR("hello_timer"), &info->hello_timer_value);
	fetch_tv(dev, BRIDGEATTR("tcn_timer"), &info->tcn_timer_value);
	fetch_tv(dev, BRIDGEATTR("topology_change_timer"),
		 &info->topology_change_timer_value);;
	fetch_tv(dev, BRIDGEATTR("gc_timer"), &info->gc_timer_value);

	info->root_port = fetch_int(dev, BRIDGEATTR("root_port"));
	info->stp_enabled = fetch_int(dev, BRIDGEATTR("stp_state"));
	info->topology_change = fetch_int(dev, BRIDGEATTR("topology_change"));
	info->topology_change_detected = fetch_int(dev,
						   BRIDGEATTR
						   ("topology_change_detected"));
	sysfs_close_class_device(dev);

	return 0;

fallback:
#endif
	return old_get_bridge_info(bridge, info);
}
示例#6
0
/**
 * sysfs_open_class_device_path: Opens and populates class device
 * @path: path to class device.
 * returns struct sysfs_class_device with success and NULL with error.
 */
struct sysfs_class_device *sysfs_open_class_device_path(const char *path)
{
    struct sysfs_class_device *cdev;
    char temp_path[SYSFS_PATH_MAX];

    if (!path) {
        errno = EINVAL;
        return NULL;
    }

    /*
     * Post linux-2.6.14 driver model supports nested classes with
     * links to the nested hierarchy at /sys/class/xxx/. Check for
     * a link to the actual class device if a directory isn't found
     */
    if (sysfs_path_is_dir(path)) {
        dprintf("%s: Directory not found, checking for a link\n", path);
        if (!sysfs_path_is_link(path)) {
            if (sysfs_get_link(path, temp_path, SYSFS_PATH_MAX)) {
                dprintf("Error retrieving link at %s\n", path);
                return NULL;
            }
        } else {
            dprintf("%s is not a valid class device path\n", path);
            return NULL;
        }
    } else
        safestrcpy(temp_path, path);

    cdev = alloc_class_device();
    if (!cdev) {
        dprintf("calloc failed\n");
        return NULL;
    }
    if (sysfs_get_name_from_path(temp_path, cdev->name, SYSFS_NAME_LEN)) {
        errno = EINVAL;
        dprintf("Error getting class device name\n");
        sysfs_close_class_device(cdev);
        return NULL;
    }

    safestrcpy(cdev->path, temp_path);
    if (sysfs_remove_trailing_slash(cdev->path)) {
        dprintf("Invalid path to class device %s\n", cdev->path);
        sysfs_close_class_device(cdev);
        return NULL;
    }
    set_classdev_classname(cdev);

    return cdev;
}
示例#7
0
/**
 * read_dir_subdirs: grabs subdirs in a specific directory
 * @sysdir: sysfs directory to read
 * returns list of directory names with success and NULL with error.
 */
struct dlist *read_dir_subdirs(const char *path)
{
	DIR *dir = NULL;
	struct dirent *dirent = NULL;
	char file_path[SYSFS_PATH_MAX], *dir_name;
	struct dlist *dirlist = NULL;

	if (!path) {
		errno = EINVAL;
		return NULL;
	}
	dir = opendir(path);
	if (!dir) {
		dprintf("Error opening directory %s\n", path);
		return NULL;
	}
	while ((dirent = readdir(dir)) != NULL) {
		if (0 == strcmp(dirent->d_name, "."))
			 continue;
		if (0 == strcmp(dirent->d_name, ".."))
			continue;
		memset(file_path, 0, SYSFS_PATH_MAX);
		safestrcpy(file_path, path);
		safestrcat(file_path, "/");
		safestrcat(file_path, dirent->d_name);
		if (!sysfs_path_is_dir(file_path)) {
			if (!dirlist) {
				dirlist = dlist_new_with_delete
					(SYSFS_NAME_LEN, sysfs_del_name);
				if (!dirlist) {
					dprintf("Error creating list\n");
					return NULL;
				}
			}
			dir_name = (char *)calloc(1, SYSFS_NAME_LEN);
			safestrcpymax(dir_name, dirent->d_name, SYSFS_NAME_LEN);
			dlist_unshift_sorted(dirlist, dir_name, sort_char);
		}
	}
	closedir(dir);
	return dirlist;
}
示例#8
0
/**
 * sysfs_open_bus: opens specific bus and all its devices on system
 * returns sysfs_bus structure with success or NULL with error.
 */
struct sysfs_bus *sysfs_open_bus(const char *name)
{
	struct sysfs_bus *bus;
	char buspath[SYSFS_PATH_MAX];

	if (!name) {
		errno = EINVAL;
		return NULL;
	}

	memset(buspath, 0, SYSFS_PATH_MAX);
	if (sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) {
		dprintf("Sysfs not supported on this system\n");
		return NULL;
	}

	safestrcat(buspath, "/");
	safestrcat(buspath, SYSFS_BUS_NAME);
	safestrcat(buspath, "/");
	safestrcat(buspath, name);
	if (sysfs_path_is_dir(buspath)) {
		dprintf("Invalid path to bus: %s\n", buspath);
		return NULL;
	}
	bus = alloc_bus();
	if (!bus) {
		dprintf("calloc failed\n");
		return NULL;
	}
	safestrcpy(bus->name, name);
	safestrcpy(bus->path, buspath);
	if (sysfs_remove_trailing_slash(bus->path)) {
		dprintf("Incorrect path to bus %s\n", bus->path);
		sysfs_close_bus(bus);
		return NULL;
	}

	return bus;
}
示例#9
0
/**
 * sysfs_open_driver_path: opens and initializes driver structure
 * @path: path to driver directory
 * returns struct sysfs_driver with success and NULL with error
 */
struct sysfs_driver *sysfs_open_driver_path(const char *path)
{
	struct sysfs_driver *driver = NULL;

	if (!path) {
		errno = EINVAL;
		return NULL;
	}
	if (sysfs_path_is_dir(path)) {
		dprintf("Invalid path to driver: %s\n", path);
		return NULL;
	}
	driver = alloc_driver();
	if (!driver) {
		dprintf("Error allocating driver at %s\n", path);
		return NULL;
	}
	if (sysfs_get_name_from_path(path, driver->name, SYSFS_NAME_LEN)) {
		dprintf("Error getting driver name from path\n");
		free(driver);
		return NULL;
	}
	safestrcpy(driver->path, path);
	if (sysfs_remove_trailing_slash(driver->path)) {
		dprintf("Invalid path to driver %s\n", driver->path);
		sysfs_close_driver(driver);
		return NULL;
	}
	if (get_driver_bus(driver)) {
		dprintf("Could not get the bus driver is on\n");
		sysfs_close_driver(driver);
		return NULL;
	}

	return driver;
}