2003-10-17 12:40:02 +04:00
/*
2009-03-26 21:29:36 +03:00
* libudev - interface to udev device information
2003-10-17 12:40:02 +04:00
*
2009-03-26 21:29:36 +03:00
* Copyright ( C ) 2008 Kay Sievers < kay . sievers @ vrfy . org >
2008-09-10 04:40:42 +04:00
*
2009-03-26 21:29:36 +03:00
* 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 .
2003-10-17 12:40:02 +04:00
*/
2003-08-06 10:57:23 +04:00
# include <stdlib.h>
# include <stdio.h>
2004-03-02 10:47:59 +03:00
# include <string.h>
2004-03-23 09:22:20 +03:00
# include <stddef.h>
2005-03-06 14:16:32 +03:00
# include <unistd.h>
2003-08-06 10:57:23 +04:00
# include <fcntl.h>
# include <string.h>
2006-08-24 02:13:07 +04:00
# include <sys/stat.h>
2003-08-06 10:57:23 +04:00
2009-06-10 01:05:25 +04:00
# include "libudev.h"
# include "libudev-private.h"
2004-11-06 16:28:01 +03:00
2008-09-06 17:45:31 +04:00
static size_t devpath_to_db_path ( struct udev * udev , const char * devpath , char * filename , size_t len )
2004-11-06 16:28:01 +03:00
{
2009-05-20 19:57:52 +04:00
char * s ;
size_t l ;
2005-08-27 04:59:20 +04:00
2009-05-20 19:57:52 +04:00
s = filename ;
l = util_strpcpyl ( & s , len , udev_get_dev_path ( udev ) , " /.udev/db/ " , NULL ) ;
2009-05-21 03:44:45 +04:00
return util_path_encode ( devpath , s , l ) ;
2004-11-06 16:28:01 +03:00
}
2003-10-18 10:32:17 +04:00
2008-10-16 19:16:58 +04:00
int udev_device_update_db ( struct udev_device * udev_device )
2003-10-18 10:32:17 +04:00
{
2008-10-16 19:16:58 +04:00
struct udev * udev = udev_device_get_udev ( udev_device ) ;
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
2008-10-06 15:52:43 +04:00
FILE * f ;
char target [ 232 ] ; /* on 64bit, tmpfs inlines up to 239 bytes */
2008-10-16 19:16:58 +04:00
size_t devlen = strlen ( udev_get_dev_path ( udev ) ) + 1 ;
2009-05-20 19:57:52 +04:00
char * s ;
size_t l ;
2008-10-16 19:16:58 +04:00
struct udev_list_entry * list_entry ;
2008-10-06 15:52:43 +04:00
int ret ;
2003-10-18 10:32:17 +04:00
2009-05-20 19:57:52 +04:00
devpath_to_db_path ( udev , udev_device_get_devpath ( udev_device ) , filename , sizeof ( filename ) ) ;
2008-10-18 22:12:55 +04:00
util_create_path ( udev , filename ) ;
2007-03-16 19:24:39 +03:00
unlink ( filename ) ;
2006-08-18 04:27:16 +04:00
2008-10-16 19:16:58 +04:00
udev_list_entry_foreach ( list_entry , udev_device_get_properties_list_entry ( udev_device ) )
if ( udev_list_entry_get_flag ( list_entry ) )
goto file ;
2008-12-28 03:49:01 +03:00
if ( udev_device_get_num_fake_partitions ( udev_device ) ! = 0 )
2008-10-06 15:52:43 +04:00
goto file ;
2008-10-16 19:16:58 +04:00
if ( udev_device_get_ignore_remove ( udev_device ) )
2008-10-06 15:52:43 +04:00
goto file ;
2008-12-28 03:49:01 +03:00
if ( udev_device_get_devlink_priority ( udev_device ) ! = 0 )
goto file ;
if ( udev_device_get_event_timeout ( udev_device ) > = 0 )
goto file ;
2009-02-23 20:31:26 +03:00
if ( udev_device_get_watch_handle ( udev_device ) > = 0 )
goto file ;
2008-12-28 03:49:01 +03:00
if ( udev_device_get_devnode ( udev_device ) = = NULL )
goto out ;
/*
* if we have only the node and symlinks to store , try not to waste
* tmpfs memory - - store values , if they fit , in a symlink target
*/
2009-05-20 19:57:52 +04:00
s = target ;
l = util_strpcpy ( & s , sizeof ( target ) , & udev_device_get_devnode ( udev_device ) [ devlen ] ) ;
2008-10-16 19:16:58 +04:00
udev_list_entry_foreach ( list_entry , udev_device_get_devlinks_list_entry ( udev_device ) ) {
2009-05-20 19:57:52 +04:00
l = util_strpcpyl ( & s , l , " " , & udev_list_entry_get_name ( list_entry ) [ devlen ] , NULL ) ;
if ( l = = 0 ) {
2008-10-16 19:16:58 +04:00
info ( udev , " size of links too large, create file \n " ) ;
2008-10-06 15:52:43 +04:00
goto file ;
2007-03-15 04:09:39 +03:00
}
2004-11-06 16:28:01 +03:00
}
2008-10-16 19:16:58 +04:00
info ( udev , " create db link (%s) \n " , target ) ;
udev_selinux_setfscreatecon ( udev , filename , S_IFLNK ) ;
2008-10-06 15:52:43 +04:00
ret = symlink ( target , filename ) ;
2008-10-16 19:16:58 +04:00
udev_selinux_resetfscreatecon ( udev ) ;
2008-10-06 15:52:43 +04:00
if ( ret = = 0 )
goto out ;
file :
f = fopen ( filename , " w " ) ;
if ( f = = NULL ) {
2008-10-16 19:16:58 +04:00
err ( udev , " unable to create db file '%s': %m \n " , filename ) ;
2008-10-06 15:52:43 +04:00
return - 1 ;
}
2008-10-16 19:16:58 +04:00
info ( udev , " created db file for '%s' in '%s' \n " , udev_device_get_devpath ( udev_device ) , filename ) ;
2008-12-28 03:49:01 +03:00
if ( udev_device_get_devnode ( udev_device ) ! = NULL ) {
fprintf ( f , " N:%s \n " , & udev_device_get_devnode ( udev_device ) [ devlen ] ) ;
udev_list_entry_foreach ( list_entry , udev_device_get_devlinks_list_entry ( udev_device ) )
fprintf ( f , " S:%s \n " , & udev_list_entry_get_name ( list_entry ) [ devlen ] ) ;
}
2008-10-16 19:16:58 +04:00
if ( udev_device_get_devlink_priority ( udev_device ) ! = 0 )
fprintf ( f , " L:%u \n " , udev_device_get_devlink_priority ( udev_device ) ) ;
if ( udev_device_get_event_timeout ( udev_device ) > = 0 )
fprintf ( f , " T:%u \n " , udev_device_get_event_timeout ( udev_device ) ) ;
if ( udev_device_get_num_fake_partitions ( udev_device ) ! = 0 )
fprintf ( f , " A:%u \n " , udev_device_get_num_fake_partitions ( udev_device ) ) ;
if ( udev_device_get_ignore_remove ( udev_device ) )
fprintf ( f , " R:%u \n " , udev_device_get_ignore_remove ( udev_device ) ) ;
2009-02-23 20:31:26 +03:00
if ( udev_device_get_watch_handle ( udev_device ) > = 0 )
fprintf ( f , " W:%u \n " , udev_device_get_watch_handle ( udev_device ) ) ;
2008-10-16 19:16:58 +04:00
udev_list_entry_foreach ( list_entry , udev_device_get_properties_list_entry ( udev_device ) ) {
if ( ! udev_list_entry_get_flag ( list_entry ) )
continue ;
fprintf ( f , " E:%s=%s \n " ,
udev_list_entry_get_name ( list_entry ) ,
udev_list_entry_get_value ( list_entry ) ) ;
2008-10-06 15:52:43 +04:00
}
fclose ( f ) ;
out :
2004-11-06 16:28:01 +03:00
return 0 ;
2003-10-18 10:32:17 +04:00
}
2008-10-16 19:16:58 +04:00
int udev_device_delete_db ( struct udev_device * udev_device )
2003-08-06 10:57:23 +04:00
{
2009-05-20 19:57:52 +04:00
struct udev * udev = udev_device_get_udev ( udev_device ) ;
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
2004-10-19 06:11:51 +04:00
2009-05-20 19:57:52 +04:00
devpath_to_db_path ( udev , udev_device_get_devpath ( udev_device ) , filename , sizeof ( filename ) ) ;
2008-10-16 19:16:58 +04:00
unlink ( filename ) ;
2003-12-20 05:29:01 +03:00
return 0 ;
2003-08-06 10:57:23 +04:00
}
2008-10-16 19:16:58 +04:00
int udev_device_rename_db ( struct udev_device * udev_device , const char * devpath_old )
2003-08-06 10:57:23 +04:00
{
2009-05-20 19:57:52 +04:00
struct udev * udev = udev_device_get_udev ( udev_device ) ;
2008-10-16 19:16:58 +04:00
char filename_old [ UTIL_PATH_SIZE ] ;
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
2003-10-21 07:28:42 +04:00
2009-05-20 19:57:52 +04:00
devpath_to_db_path ( udev , devpath_old , filename_old , sizeof ( filename_old ) ) ;
devpath_to_db_path ( udev , udev_device_get_devpath ( udev_device ) , filename , sizeof ( filename ) ) ;
2008-10-16 19:16:58 +04:00
return rename ( filename_old , filename ) ;
2003-10-21 07:28:42 +04:00
}