2005-07-22 20:35:58 +04:00
/*
* udev_utils . c - generic stuff used by udev
*
* Copyright ( C ) 2004 , 2005 Kay Sievers < kay . sievers @ vrfy . org >
*
* This program is free software ; you can redistribute it and / or modify it
* 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 0213 9 , USA .
*
*/
# include <stdlib.h>
# include <stdio.h>
# include <stddef.h>
# include <unistd.h>
# include <fcntl.h>
# include <errno.h>
# include <ctype.h>
2006-01-09 23:18:00 +03:00
2005-07-22 20:35:58 +04:00
# include "udev.h"
2006-01-09 23:18:00 +03:00
# include "udev_rules.h"
2005-07-22 20:35:58 +04:00
2006-01-09 23:18:00 +03:00
struct udevice * udev_device_init ( void )
2005-07-22 20:35:58 +04:00
{
2006-01-09 23:18:00 +03:00
struct udevice * udev ;
2005-07-22 20:35:58 +04:00
2006-01-09 23:18:00 +03:00
udev = malloc ( sizeof ( struct udevice ) ) ;
if ( udev = = NULL )
return NULL ;
2005-07-22 20:35:58 +04:00
memset ( udev , 0x00 , sizeof ( struct udevice ) ) ;
2006-01-09 23:18:00 +03:00
2005-07-22 20:35:58 +04:00
INIT_LIST_HEAD ( & udev - > symlink_list ) ;
INIT_LIST_HEAD ( & udev - > run_list ) ;
INIT_LIST_HEAD ( & udev - > env_list ) ;
2006-01-09 23:18:00 +03:00
/* set sysfs device to local storage, can be overridden if needed */
udev - > dev = & udev - > dev_local ;
2005-07-22 20:35:58 +04:00
2006-01-09 23:18:00 +03:00
/* default node permissions */
udev - > mode = 0660 ;
strcpy ( udev - > owner , " root " ) ;
strcpy ( udev - > group , " root " ) ;
2005-07-22 20:35:58 +04:00
2006-01-09 23:18:00 +03:00
return udev ;
2005-07-22 20:35:58 +04:00
}
2006-01-09 23:18:00 +03:00
void udev_device_cleanup ( struct udevice * udev )
2005-07-22 20:35:58 +04:00
{
2005-08-27 18:15:41 +04:00
name_list_cleanup ( & udev - > symlink_list ) ;
name_list_cleanup ( & udev - > run_list ) ;
name_list_cleanup ( & udev - > env_list ) ;
2006-01-09 23:18:00 +03:00
free ( udev ) ;
}
dev_t udev_device_get_devt ( struct udevice * udev )
{
const char * attr ;
unsigned int major , minor ;
/* read it from sysfs */
attr = sysfs_attr_get_value ( udev - > dev - > devpath , " dev " ) ;
if ( attr ! = NULL ) {
if ( sscanf ( attr , " %u:%u " , & major , & minor ) = = 2 )
return makedev ( major , minor ) ;
}
return makedev ( 0 , 0 ) ;
}
int udev_device_event ( struct udev_rules * rules , struct udevice * udev )
{
int retval = 0 ;
/* device node or netif */
if ( ( major ( udev - > devt ) ! = 0 | | strcmp ( udev - > dev - > subsystem , " net " ) = = 0 ) & &
strcmp ( udev - > action , " add " ) = = 0 ) {
dbg ( " device node or netif add '%s' " , udev - > dev - > devpath ) ;
udev_rules_get_name ( rules , udev ) ;
if ( udev - > ignore_device ) {
info ( " device event will be ignored " ) ;
2006-01-25 04:21:07 +03:00
return 0 ;
2006-01-09 23:18:00 +03:00
}
/* create node, store in db */
if ( udev - > name [ 0 ] ! = ' \0 ' )
retval = udev_add_device ( udev ) ;
else
info ( " device node creation supressed " ) ;
2006-01-25 04:21:07 +03:00
return retval ;
2006-01-09 23:18:00 +03:00
}
if ( major ( udev - > devt ) ! = 0 & & strcmp ( udev - > action , " remove " ) = = 0 ) {
struct name_entry * name_loop ;
udev_rules_get_run ( rules , udev ) ;
if ( udev - > ignore_device ) {
info ( " device event will be ignored " ) ;
2006-01-25 04:21:07 +03:00
return 0 ;
2006-01-09 23:18:00 +03:00
}
/* get data from db, remove db-entry, delete node */
retval = udev_remove_device ( udev ) ;
/* restore stored persistent data */
list_for_each_entry ( name_loop , & udev - > env_list , node )
putenv ( name_loop - > name ) ;
2006-01-25 04:21:07 +03:00
return retval ;
2006-01-09 23:18:00 +03:00
}
2006-01-25 04:21:07 +03:00
/* default devices without a node */
2006-01-09 23:18:00 +03:00
udev_rules_get_run ( rules , udev ) ;
2006-01-25 04:21:07 +03:00
if ( udev - > ignore_device )
2006-01-09 23:18:00 +03:00
info ( " device event will be ignored " ) ;
return retval ;
2005-07-22 20:35:58 +04:00
}