2003-10-17 12:40:02 +04:00
/*
2008-10-16 19:16:58 +04:00
* Copyright ( C ) 2008 Kay Sievers < kay . sievers @ vrfy . org >
2003-10-17 12:40:02 +04:00
*
2008-09-10 04:40:42 +04:00
* 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 , either version 2 of the License , or
* ( at your option ) any later version .
2003-10-17 12:40:02 +04:00
*
2008-09-10 04:40:42 +04:00
* 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 , see < http : //www.gnu.org/licenses/>.
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
2003-10-16 10:50:13 +04:00
# include "udev.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
{
2007-03-14 23:41:33 +03:00
size_t start ;
2005-08-27 04:59:20 +04:00
2008-03-29 18:12:41 +03:00
/* translate to location of db file */
2008-09-10 20:59:42 +04:00
util_strlcpy ( filename , udev_get_dev_path ( udev ) , len ) ;
start = util_strlcat ( filename , " /.udev/db/ " , len ) ;
util_strlcat ( filename , devpath , len ) ;
2008-09-10 20:39:23 +04:00
return util_path_encode ( & filename [ start ] , len - start ) ;
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 ;
struct udev_list_entry * list_entry ;
2008-10-06 15:52:43 +04:00
int ret ;
2003-10-18 10:32:17 +04:00
2008-10-16 19:16:58 +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 ;
if ( udev_device_get_num_fake_partitions ( udev_device ) )
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-10-16 19:16:58 +04:00
/* try not to waste tmpfs memory; store values, if they fit, in a symlink target */
util_strlcpy ( target , & udev_device_get_devnode ( udev_device ) [ devlen ] , sizeof ( target ) ) ;
udev_list_entry_foreach ( list_entry , udev_device_get_devlinks_list_entry ( udev_device ) ) {
2008-10-06 15:52:43 +04:00
size_t len ;
2006-08-18 04:27:16 +04:00
2008-10-06 15:52:43 +04:00
util_strlcat ( target , " " , sizeof ( target ) ) ;
2008-10-16 19:16:58 +04:00
len = util_strlcat ( target , & udev_list_entry_get_name ( list_entry ) [ devlen ] , sizeof ( target ) ) ;
2008-10-06 15:52:43 +04:00
if ( len > = sizeof ( target ) ) {
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 ) ;
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 ] ) ;
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 ) ) ;
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
{
2008-09-10 23:50:21 +04:00
char filename [ UTIL_PATH_SIZE ] ;
2004-10-19 06:11:51 +04:00
2008-10-16 19:16:58 +04:00
devpath_to_db_path ( udev_device_get_udev ( udev_device ) ,
udev_device_get_devpath ( udev_device ) ,
filename , sizeof ( filename ) ) ;
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
{
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
2008-10-16 19:16:58 +04:00
devpath_to_db_path ( udev_device_get_udev ( udev_device ) ,
devpath_old ,
filename_old , sizeof ( filename_old ) ) ;
devpath_to_db_path ( udev_device_get_udev ( udev_device ) ,
udev_device_get_devpath ( udev_device ) ,
filename , sizeof ( filename ) ) ;
return rename ( filename_old , filename ) ;
2003-10-21 07:28:42 +04:00
}