/*
 * sysfs_dir.c
 *
 * Directory 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"

static int sort_char(void *new, void *old)
{
	return ((strncmp((char *)new, (char *)old,
			strlen((char *)new))) < 0 ? 1 : 0);
}

/**
 * sysfs_del_name: free function for sysfs_open_subsystem_list
 * @name: memory area to be freed
 */
static void sysfs_del_name(void *name)
{
	free(name);
}

/**
 * sysfs_del_attribute: routine for dlist integration
 */
static void sysfs_del_attribute(void *attr)
{
	sysfs_close_attribute((struct sysfs_attribute *)attr);
}

/**
 * attr_name_equal: compares attributes by name
 * @a: attribute name for comparison
 * @b: sysfs_attribute to be compared.
 * returns 1 if a==b->name or 0 if not equal
 */
static int attr_name_equal(void *a, void *b)
{
	if (!a || !b)
		return 0;

	if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0)
		return 1;

	return 0;
}

/**
 * sysfs_close_attribute: closes and cleans up attribute
 * @sysattr: attribute to close.
 */
void sysfs_close_attribute(struct sysfs_attribute *sysattr)
{
	if (sysattr) {
		if (sysattr->value)
			free(sysattr->value);
		free(sysattr);
	}
}

/**
 * alloc_attribute: allocates and initializes attribute structure
 * returns struct sysfs_attribute with success and NULL with error.
 */
static struct sysfs_attribute *alloc_attribute(void)
{
	return (struct sysfs_attribute *)
			calloc(1, sizeof(struct sysfs_attribute));
}

/**
 * sysfs_open_attribute: creates sysfs_attribute structure
 * @path: path to attribute.
 * returns sysfs_attribute struct with success and NULL with error.
 */
struct sysfs_attribute *sysfs_open_attribute(const char *path)
{
	struct sysfs_attribute *sysattr = NULL;
	struct stat fileinfo;

	if (!path) {
		errno = EINVAL;
		return NULL;
	}
	sysattr = alloc_attribute();
	if (!sysattr) {
		dprintf("Error allocating attribute at %s\n", path);
		return NULL;
	}
	if (sysfs_get_name_from_path(path, sysattr->name,
				SYSFS_NAME_LEN) != 0) {
		dprintf("Error retrieving attrib name from path: %s\n", path);
		sysfs_close_attribute(sysattr);
		return NULL;
	}
	safestrcpy(sysattr->path, path);
	if ((stat(sysattr->path, &fileinfo)) != 0) {
		dprintf("Stat failed: No such attribute?\n");
		sysattr->method = 0;
		free(sysattr);
		sysattr = NULL;
	} else {
		if (fileinfo.st_mode & S_IRUSR)
			sysattr->method |= SYSFS_METHOD_SHOW;
		if (fileinfo.st_mode & S_IWUSR)
			sysattr->method |= SYSFS_METHOD_STORE;
	}

	return sysattr;
}

/**
 * sysfs_read_attribute: reads value from attribute
 * @sysattr: attribute to read
 * returns 0 with success and -1 with error.
 */
int sysfs_read_attribute(struct sysfs_attribute *sysattr)
{
	char *fbuf = NULL;
	char *vbuf = NULL;
	ssize_t length = 0;
	long pgsize = 0;
	int fd;

	if (!sysattr) {
		errno = EINVAL;
		return -1;
	}
	if (!(sysattr->method & SYSFS_METHOD_SHOW)) {
		dprintf("Show method not supported for attribute %s\n",
			sysattr->path);
		errno = EACCES;
		return -1;
	}
	pgsize = getpagesize();
	fbuf = (char *)calloc(1, pgsize+1);
	if (!fbuf) {
		dprintf("calloc failed\n");
		return -1;
	}
	if ((fd = open(sysattr->path, O_RDONLY)) < 0) {
		dprintf("Error reading attribute %s\n", sysattr->path);
		free(fbuf);
		return -1;
	}
	length = read(fd, fbuf, pgsize);
	if (length < 0) {
		dprintf("Error reading from attribute %s\n", sysattr->path);
		close(fd);
		free(fbuf);
		return -1;
	}
	if (sysattr->len > 0) {
		if ((sysattr->len == length) &&
				(!(strncmp(sysattr->value, fbuf, length)))) {
			close(fd);
			free(fbuf);
			return 0;
		}
		free(sysattr->value);
	}
	sysattr->len = length;
	close(fd);
	vbuf = (char *)realloc(fbuf, length+1);
	if (!vbuf) {
		dprintf("realloc failed\n");
		free(fbuf);
		return -1;
	}
	sysattr->value = vbuf;

	return 0;
}

/**
 * sysfs_write_attribute: write value to the attribute
 * @sysattr: attribute to write
 * @new_value: value to write
 * @len: length of "new_value"
 * returns 0 with success and -1 with error.
 */
int sysfs_write_attribute(struct sysfs_attribute *sysattr,
		const char *new_value, size_t len)
{
	int fd;
	int length;

	if (!sysattr || !new_value || len == 0) {
		errno = EINVAL;
		return -1;
	}

	if (!(sysattr->method & SYSFS_METHOD_STORE)) {
		dprintf ("Store method not supported for attribute %s\n",
			sysattr->path);
		errno = EACCES;
		return -1;
	}
	if (sysattr->method & SYSFS_METHOD_SHOW) {
		/*
		 * read attribute again to see if we can get an updated value
		 */
		if ((sysfs_read_attribute(sysattr))) {
			dprintf("Error reading attribute\n");
			return -1;
		}
		if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0 &&
				(len == sysattr->len)) {
			dprintf("Attr %s already has the requested value %s\n",
					sysattr->name, new_value);
			return 0;
		}
	}
	/*
	 * open O_WRONLY since some attributes have no "read" but only
	 * "write" permission
	 */
	if ((fd = open(sysattr->path, O_WRONLY)) < 0) {
		dprintf("Error reading attribute %s\n", sysattr->path);
		return -1;
	}

	length = write(fd, new_value, len);
	if (length < 0) {
		dprintf("Error writing to the attribute %s - invalid value?\n",
			sysattr->name);
		close(fd);
		return -1;
	} else if ((unsigned int)length != len) {
		dprintf("Could not write %zd bytes to attribute %s\n",
					len, sysattr->name);
		/*
		 * since we could not write user supplied number of bytes,
		 * restore the old value if one available
		 */
		if (sysattr->method & SYSFS_METHOD_SHOW) {
			length = write(fd, sysattr->value, sysattr->len);
			close(fd);
			return -1;
		}
	}

	/*
	 * Validate length that has been copied. Alloc appropriate area
	 * in sysfs_attribute. Verify first if the attribute supports reading
	 * (show method). If it does not, do not bother
	 */
	if (sysattr->method & SYSFS_METHOD_SHOW) {
		if (length != sysattr->len) {
			sysattr->value = (char *)realloc
				(sysattr->value, length);
			sysattr->len = length;
			safestrcpymax(sysattr->value, new_value, length);
		} else {
			/*"length" of the new value is same as old one */
			safestrcpymax(sysattr->value, new_value, length);
		}
	}

	close(fd);
	return 0;
}

/**
 * add_attribute_to_list: open and add attribute at path to given dlist
 * @list: dlist attribute is to be added
 * @path: path to attribute
 * returns pointer to attr added with success and NULL with error.
 */
static struct sysfs_attribute *add_attribute_to_list(struct dlist *alist,
							const char *path)
{
	struct sysfs_attribute *attr;

	attr = sysfs_open_attribute(path);
	if (!attr) {
		dprintf("Error opening attribute %s\n",	path);
		return NULL;
	}
	if (attr->method & SYSFS_METHOD_SHOW) {
		if (sysfs_read_attribute(attr)) {
			dprintf("Error reading attribute %s\n",	path);
			sysfs_close_attribute(attr);
			return NULL;
		}
	}

	if (!alist) {
		alist = dlist_new_with_delete
			(sizeof(struct sysfs_attribute), sysfs_del_attribute);
	}
	dlist_unshift_sorted(alist, attr, sort_list);
	return attr;
}

/**
 * add_attribute: open and add attribute at path to given directory
 * @dev: device whose attribute is to be added
 * @path: path to attribute
 * returns pointer to attr added with success and NULL with error.
 */
static struct sysfs_attribute *add_attribute(void *dev, const char *path)
{
	struct sysfs_attribute *attr;

	attr = sysfs_open_attribute(path);
	if (!attr) {
		dprintf("Error opening attribute %s\n",	path);
		return NULL;
	}
	if (attr->method & SYSFS_METHOD_SHOW) {
		if (sysfs_read_attribute(attr)) {
			dprintf("Error reading attribute %s\n",	path);
			sysfs_close_attribute(attr);
			return NULL;
		}
	}

	if (!((struct sysfs_device *)dev)->attrlist) {
		((struct sysfs_device *)dev)->attrlist = dlist_new_with_delete
			(sizeof(struct sysfs_attribute), sysfs_del_attribute);
	}
	dlist_unshift_sorted(((struct sysfs_device *)dev)->attrlist,
			attr, sort_list);

	return attr;
}

/*
 * get_attribute - given a sysfs_* struct and a name, return the
 * sysfs_attribute corresponding to "name"
 * returns sysfs_attribute on success and NULL on error
 */
struct sysfs_attribute *get_attribute(void *dev, const char *name)
{
	struct sysfs_attribute *cur = NULL;
	char path[SYSFS_PATH_MAX];

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

	if (((struct sysfs_device *)dev)->attrlist) {
		/* check if attr is already in the list */
		cur = (struct sysfs_attribute *)dlist_find_custom
			((((struct sysfs_device *)dev)->attrlist),
			 	(void *)name, attr_name_equal);
		if (cur)
			return cur;
	}
	safestrcpymax(path, ((struct sysfs_device *)dev)->path,
			SYSFS_PATH_MAX);
	safestrcatmax(path, "/", SYSFS_PATH_MAX);
	safestrcatmax(path, name, SYSFS_PATH_MAX);
	if (!sysfs_path_is_file(path))
		cur = add_attribute((void *)dev, path);
	return cur;
}

/**
 * read_dir_links: grabs links in a specific directory
 * @sysdir: sysfs directory to read
 * returns list of link names with success and NULL with error.
 */
struct dlist *read_dir_links(const char *path)
{
	DIR *dir = NULL;
	struct dirent *dirent = NULL;
	char file_path[SYSFS_PATH_MAX], *linkname;
	struct dlist *linklist = 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_link(file_path)) {
			if (!linklist) {
				linklist = dlist_new_with_delete
					(SYSFS_NAME_LEN, sysfs_del_name);
				if (!linklist) {
					dprintf("Error creating list\n");
					return NULL;
				}
			}
			linkname = (char *)calloc(1, SYSFS_NAME_LEN);
			safestrcpymax(linkname, dirent->d_name, SYSFS_NAME_LEN);
			dlist_unshift_sorted(linklist, linkname, sort_char);
		}
	}
	closedir(dir);
	return linklist;
}

void sysfs_close_dev_tree(void *dev);

int add_subdirectory(struct sysfs_device *dev, char *path)
{
	struct sysfs_device *newdev;

	if (!path)
		return -1;

	newdev = sysfs_open_device_path(path);
	if (newdev == NULL)
		return -1;

	if (dev->children == NULL)
		dev->children = dlist_new_with_delete(
			sizeof(struct sysfs_device), sysfs_close_dev_tree);

	dlist_unshift_sorted(dev->children, newdev, sort_list);
	return 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;
}

/**
 * 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;
}

/**
 * get_attributes_list: build a list of attributes for the given path
 * @path: grab attributes at the given path
 * returns dlist of attributes on success and NULL on failure
 */
struct dlist *get_attributes_list(struct dlist *alist, const char *path)
{
	DIR *dir = NULL;
	struct dirent *dirent = NULL;
	char file_path[SYSFS_PATH_MAX];

	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_file(file_path)) {
			if (!alist) {
				alist = dlist_new_with_delete
					(sizeof(struct sysfs_attribute),
							sysfs_del_attribute);
				if (!alist) {
					dprintf("Error creating list\n");
					return NULL;
				}
			}
			add_attribute_to_list(alist, file_path);
		}
	}
	closedir(dir);
	return alist;
}

/**
 * get_dev_attributes_list: build a list of attributes for the given device
 * @dev: devices whose attributes list is required
 * returns dlist of attributes on success and NULL on failure
 */
struct dlist *get_dev_attributes_list(void *dev)
{
	DIR *dir = NULL;
	struct dirent *dirent = NULL;
	struct sysfs_attribute *attr = NULL;
	char file_path[SYSFS_PATH_MAX], path[SYSFS_PATH_MAX];

	if (!dev) {
		errno = EINVAL;
		return NULL;
	}
	memset(path, 0, SYSFS_PATH_MAX);
	safestrcpy(path, ((struct sysfs_device *)dev)->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_file(file_path)) {
			if (((struct sysfs_device *)dev)->attrlist) {
				/* check if attr is already in the list */
				attr = (struct sysfs_attribute *)
				dlist_find_custom
				((((struct sysfs_device *)dev)->attrlist),
			 	(void *)dirent->d_name, attr_name_equal);
				if (attr)
					continue;
				else
					add_attribute(dev, file_path);
			} else
				attr = add_attribute(dev, file_path);
		}
	}
	closedir(dir);
	return ((struct sysfs_device *)dev)->attrlist;
}
