namedev.c revision 83be97ba211c4f69e7fd9f16f57ca7210a116a7d
/*
*
* Userspace devfs
*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
*
*
* under the terms of the GNU General Public License as published by the
* Free Software Foundation version 2 of the License.
*
* This program 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include "list.h"
#include "udev.h"
#include "udev_version.h"
#include "namedev.h"
#include "libsysfs/libsysfs.h"
#include "klibc_fixups.h"
/* compare string with pattern (supports * ? [0-9] [!A-Z]) */
static int strcmp_pattern(const char *p, const char *s)
{
if (*s == '\0') {
while (*p == '*')
p++;
return (*p != '\0');
}
switch (*p) {
case '[':
{
int not = 0;
p++;
if (*p == '!') {
not = 1;
p++;
}
while (*p && (*p != ']')) {
int match = 0;
if (p[1] == '-') {
if ((*s >= *p) && (*s <= p[2]))
match = 1;
p += 3;
} else {
match = (*p == *s);
p++;
}
while (*p && (*p != ']'))
p++;
}
}
}
break;
case '*':
if (strcmp_pattern(p, s+1))
return strcmp_pattern(p+1, s);
return 0;
case '\0':
if (*s == '\0') {
return 0;
}
break;
default:
if ((*p == *s) || (*p == '?'))
break;
}
return 1;
}
if (b->var) \
#define copy_string(a, b, var) \
{
struct config_device *tmp_dev;
/* update the values if we already have the device */
continue;
continue;
return 0;
}
/* not found, add new structure to the device list */
if (!tmp_dev)
return -ENOMEM;
//dump_config_dev(tmp_dev);
return 0;
}
{
struct perm_device *tmp_dev;
/* update the values if we already have the device */
continue;
return 0;
}
/* not found, add new structure to the perm list */
if (!tmp_dev)
return -ENOMEM;
//dump_perm_dev(tmp_dev);
return 0;
}
{
continue;
return perm;
}
return NULL;
}
{
if (strlen(default_mode_str) != 0) {
}
return mode;
}
{
char *dig;
/* FIXME, figure out how to handle stuff like sdaj which will not work right now. */
dig--;
}
{
char *pos;
while (1) {
if (pos) {
*pos = 0x00;
switch (pos[1]) {
case 'b':
break;
break;
case 'n':
break;
break;
case 'D':
break;
}
break;
case 'm':
break;
case 'M':
break;
case 'c':
break;
break;
default:
break;
}
} else
break;
}
}
{
int retval;
int res;
int status;
int fds[2];
int value_set = 0;
char buffer[256];
char *arg;
char *args[CALLOUT_MAXARG];
int i;
if (retval != 0) {
dbg("pipe failed");
return -1;
}
if (pid == -1) {
dbg("fork failed");
return -1;
}
if (pid == 0) {
/* child */
/* callout with arguments */
for (i=0; i < CALLOUT_MAXARG-1; i++) {
break;
}
if (args[i]) {
dbg("too many args - %d", i);
}
} else {
}
if (retval != 0) {
dbg("child execve failed");
exit(1);
}
return -1; /* avoid compiler warning */
} else {
/* parent reads from fds[0] */
retval = 0;
while (1) {
if (res <= 0)
break;
retval = -1;
}
if (value_set) {
dbg("callout value already set");
retval = -1;
} else {
value_set = 1;
}
}
if (res < 0) {
retval = -1;
}
#ifndef __KLIBC__
retval = -1;
}
#endif
}
return retval;
}
static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
{
struct config_device *dev;
continue;
if (sysfs_device) {
continue;
}
/* substitute anything that needs to be in the program name */
continue;
continue;
dbg("callout returned matching value '%s', '%s' becomes '%s'",
return 0;
}
return -ENODEV;
}
static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
{
struct config_device *dev;
char *c;
continue;
if (sysfs_device) {
continue;
}
/* try to find the attribute in the class device directory */
if (tmpattr)
goto label_found;
/* look in the class device directory if present */
if (sysfs_device) {
if (tmpattr)
goto label_found;
}
continue;
if (*c == '\n')
*c = 0x00;
dbg("compare attribute '%s' value '%s' with '%s'",
continue;
dbg("found matching attribute '%s', '%s' becomes '%s' ",
return 0;
}
return -ENODEV;
}
static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
{
struct config_device *dev;
char path[SYSFS_PATH_MAX];
int found;
/* we have to have a sysfs device for NUMBER to work */
if (!sysfs_device)
return -ENODEV;
continue;
continue;
found = 0;
found = 1;
} else {
*temp = 0x00;
found = 1;
}
if (!found)
continue;
dbg("found matching id '%s', '%s' becomes '%s'",
return 0;
}
return -ENODEV;
}
static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
{
struct config_device *dev;
char path[SYSFS_PATH_MAX];
int found;
/* we have to have a sysfs device for TOPOLOGY to work */
if (!sysfs_device)
return -ENODEV;
continue;
continue;
found = 0;
found = 1;
} else {
*temp = 0x00;
found = 1;
}
if (!found)
continue;
dbg("found matching place '%s', '%s' becomes '%s'",
return 0;
}
return -ENODEV;
}
static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
{
struct config_device *dev;
continue;
continue;
return 0;
}
return -ENODEV;
}
{
/* heh, this is pretty simple... */
}
{
int retval = 0;
struct perm_device *perm;
/* find the sysfs_device for this class device */
/* Wouldn't it really be nice if libsysfs could do this for us? */
} else {
/* bah, let's go backwards up a level to see if the device is there,
* as block partitions don't point to the physical device. Need to fix that
* up in the kernel...
*/
dbg("looking at block device");
char path[SYSFS_PATH_MAX];
dbg("really is a partition");
*temp = 0x00;
if (class_dev_parent == NULL) {
} else {
if (class_dev_parent->sysdevice)
}
}
}
}
if (sysfs_device) {
} else {
}
/* rules are looked at in priority order */
if (retval == 0)
goto found;
if (retval == 0)
goto found;
if (retval == 0)
goto found;
if (retval == 0)
goto found;
if (retval == 0)
goto found;
goto done;
/* substitute placeholder in NAME */
done:
if (perm) {
} else {
/* no matching perms found :( */
}
dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o",
if (class_dev_parent)
return 0;
}
int namedev_init(void)
{
int retval;
retval = namedev_init_rules();
if (retval)
return retval;
if (retval)
return retval;
return retval;
}