/* * sysfs_module.c * * Generic module utility functions for libsysfs * * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "libsysfs.h" #include "sysfs.h" /** * mod_name_equal: compares modules' name * @a: module_name looking for * @b: sysfs_module being compared */ static int mod_name_equal(void *a, void *b) { if (a == NULL || b == NULL) return 0; if (strcmp(((char *)a), ((struct sysfs_module *)b)->name) == 0) return 1; return 0; } /** * sysfs_close_module: closes a module. * @module: sysfs_module device to close. */ void sysfs_close_module(struct sysfs_module *module) { /* * since both parms and sections are attribs _under_ the * subdir of module->directory, they will get closed by * this single call */ if (module != NULL) { if (module->attrlist != NULL) dlist_destroy(module->attrlist); if (module->parmlist != NULL) dlist_destroy(module->parmlist); if (module->sections != NULL) dlist_destroy(module->sections); free(module); } } /** * alloc_module: callocs and initializes new module struct. * returns sysfs_module or NULL. */ static struct sysfs_module *alloc_module(void) { return (struct sysfs_module *)calloc(1, sizeof(struct sysfs_module)); } /** * sysfs_open_module_path: Opens and populates the module struct * @path: path to module. * returns struct sysfs_module with success and NULL with error. */ struct sysfs_module *sysfs_open_module_path(const char *path) { struct sysfs_module *mod = NULL; if (path == NULL) { errno = EINVAL; return NULL; } if ((sysfs_path_is_dir(path)) != 0) { dprintf("%s is not a valid path to a module\n", path); return NULL; } mod = alloc_module(); if (mod == NULL) { dprintf("calloc failed\n"); return NULL; } if ((sysfs_get_name_from_path(path, mod->name, SYSFS_NAME_LEN)) != 0) { errno = EINVAL; dprintf("Error getting module name\n"); sysfs_close_module(mod); return NULL; } safestrcpy(mod->path, path); if ((sysfs_remove_trailing_slash(mod->path)) != 0) { dprintf("Invalid path to module %s\n", mod->path); sysfs_close_module(mod); return NULL; } return mod; } /** * sysfs_open_module: opens specific module on a system * returns sysfs_module structure with success or NULL with error. */ struct sysfs_module *sysfs_open_module(const char *name) { struct sysfs_module *mod = NULL; char modpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; return NULL; } memset(modpath, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(modpath, SYSFS_PATH_MAX)) != 0) { dprintf("Sysfs not supported on this system\n"); return NULL; } safestrcat(modpath, "/"); safestrcat(modpath, SYSFS_MODULE_NAME); safestrcat(modpath, "/"); safestrcat(modpath, name); if ((sysfs_path_is_dir(modpath)) != 0) { dprintf("Module %s not found on the system\n", name); return NULL; } mod = alloc_module(); if (mod == NULL) { dprintf("calloc failed\n"); return NULL; } safestrcpy(mod->name, name); safestrcpy(mod->path, modpath); if ((sysfs_remove_trailing_slash(mod->path)) != 0) { dprintf("Invalid path to module %s\n", mod->path); sysfs_close_module(mod); return NULL; } return mod; } /** * sysfs_get_module_attributes: returns a dlist of attributes for * the requested sysfs_module * @cdev: sysfs_module for which attributes are needed * returns a dlist of attributes if exists, NULL otherwise */ struct dlist *sysfs_get_module_attributes(struct sysfs_module *module) { if (module == NULL) { errno = EINVAL; return NULL; } return get_dev_attributes_list(module); } /** * sysfs_get_module_attr: searches module's attributes by name * @module: module to look through * @name: attribute name to get * returns sysfs_attribute reference with success or NULL with error */ struct sysfs_attribute *sysfs_get_module_attr (struct sysfs_module *module, const char *name) { if (module == NULL || name == NULL) { errno = EINVAL; return NULL; } return get_attribute(module, (char *)name); } /** * sysfs_get_module_parms: Get modules list of parameters * @module: sysfs_module whose parmameter list is required * Returns dlist of parameters on SUCCESS and NULL on error */ struct dlist *sysfs_get_module_parms(struct sysfs_module *module) { char ppath[SYSFS_PATH_MAX]; if (module == NULL) { errno = EINVAL; return NULL; } memset(ppath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, module->path); safestrcat(ppath,"/"); safestrcat(ppath, SYSFS_MOD_PARM_NAME); return (get_attributes_list(module->parmlist, ppath)); } /** * sysfs_get_module_sections: Get the set of sections for this module * @module: sysfs_module whose list of sections is required * Returns dlist of sections on SUCCESS and NULL on error */ struct dlist *sysfs_get_module_sections(struct sysfs_module *module) { char ppath[SYSFS_PATH_MAX]; if (module == NULL) { errno = EINVAL; return NULL; } memset(ppath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, module->path); safestrcat(ppath,"/"); safestrcat(ppath, SYSFS_MOD_SECT_NAME); return (get_attributes_list(module->sections, ppath)); } /** * sysfs_get_module_parm: * @module: sysfs_module to look through * @parm: name of the parameter to look for * Returns sysfs_attribute * on SUCCESS and NULL on error */ struct sysfs_attribute *sysfs_get_module_parm (struct sysfs_module *module, const char *parm) { struct dlist *parm_list = NULL; if (module == NULL || parm == NULL) { errno = EINVAL; return NULL; } parm_list = sysfs_get_module_parms(module); if (parm_list == NULL) return NULL; return (struct sysfs_attribute *)dlist_find_custom(parm_list, (void *)parm, mod_name_equal); } /** * sysfs_get_module_section * @module: sysfs_module to look through * @section: name of the section to look for * Returns sysfs_attribute * on SUCCESS and NULL on error */ struct sysfs_attribute *sysfs_get_module_section (struct sysfs_module *module, const char *section) { struct dlist *sect_list = NULL; if (module == NULL || section == NULL) { errno = EINVAL; return NULL; } sect_list = sysfs_get_module_sections(module); if (sect_list == NULL) return NULL; return (struct sysfs_attribute *)dlist_find_custom(sect_list, (void *)section, mod_name_equal); }