2004-03-23 09:22:20 +03:00
/*
2005-07-22 20:35:58 +04:00
* udev_utils . c - generic stuff used by udev
2004-03-23 09:22:20 +03:00
*
2005-07-22 20:35:58 +04:00
* Copyright ( C ) 2004 - 2005 Kay Sievers < kay . sievers @ vrfy . org >
2004-03-23 09:22:20 +03: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 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>
2004-03-27 12:21:46 +03:00
# include <stddef.h>
2004-03-23 09:22:20 +03:00
# include <unistd.h>
# include <fcntl.h>
2004-03-27 12:21:46 +03:00
# include <errno.h>
2004-12-20 09:38:33 +03:00
# include <ctype.h>
2004-03-27 12:21:46 +03:00
# include <dirent.h>
2005-06-05 07:11:29 +04:00
# include <syslog.h>
2004-11-13 14:36:47 +03:00
# include <sys/utsname.h>
2004-03-23 09:22:20 +03:00
2005-03-07 06:29:43 +03:00
# include "udev_libc_wrapper.h"
2004-03-23 09:22:20 +03:00
# include "udev.h"
2004-03-27 12:21:46 +03:00
# include "logging.h"
2004-11-25 04:44:38 +03:00
# include "udev_utils.h"
2004-03-27 12:21:46 +03:00
# include "list.h"
2004-03-23 09:22:20 +03:00
2005-06-05 07:11:29 +04:00
int log_priority ( const char * priority )
{
char * endptr ;
int prio ;
prio = strtol ( priority , & endptr , 10 ) ;
if ( endptr [ 0 ] = = ' \0 ' )
return prio ;
if ( strncasecmp ( priority , " err " , 3 ) = = 0 )
return LOG_ERR ;
if ( strcasecmp ( priority , " info " ) = = 0 )
return LOG_INFO ;
if ( strcasecmp ( priority , " debug " ) = = 0 )
return LOG_DEBUG ;
if ( string_is_true ( priority ) )
return LOG_ERR ;
return 0 ;
}
2005-02-06 03:39:25 +03:00
int kernel_release_satisfactory ( unsigned int version , unsigned int patchlevel , unsigned int sublevel )
2004-11-13 14:36:47 +03:00
{
2005-02-06 03:39:25 +03:00
static unsigned int kversion = 0 ;
static unsigned int kpatchlevel ;
static unsigned int ksublevel ;
2004-11-13 14:36:47 +03:00
if ( kversion = = 0 ) {
2004-11-23 05:43:37 +03:00
struct utsname uts ;
2004-11-13 14:36:47 +03:00
if ( uname ( & uts ) ! = 0 )
return - 1 ;
if ( sscanf ( uts . release , " %u.%u.%u " , & kversion , & kpatchlevel , & ksublevel ) ! = 3 ) {
kversion = 0 ;
return - 1 ;
}
}
if ( kversion > = version & & kpatchlevel > = patchlevel & & ksublevel > = sublevel )
return 1 ;
else
return 0 ;
}
2005-03-04 23:33:57 +03:00
int name_list_add ( struct list_head * name_list , const char * name , int sort )
2004-03-27 12:21:46 +03:00
{
2005-02-21 16:48:12 +03:00
struct name_entry * loop_name ;
struct name_entry * new_name ;
list_for_each_entry ( loop_name , name_list , node ) {
/* avoid doubles */
if ( strcmp ( loop_name - > name , name ) = = 0 ) {
dbg ( " '%s' is already in the list " , name ) ;
return 0 ;
2004-03-27 12:21:46 +03:00
}
}
2005-06-26 20:55:24 +04:00
if ( sort )
list_for_each_entry ( loop_name , name_list , node ) {
if ( sort & & strcmp ( loop_name - > name , name ) > 0 )
break ;
}
2005-02-21 16:48:12 +03:00
new_name = malloc ( sizeof ( struct name_entry ) ) ;
if ( new_name = = NULL ) {
2004-03-27 12:21:46 +03:00
dbg ( " error malloc " ) ;
return - ENOMEM ;
}
2005-03-07 06:29:43 +03:00
strlcpy ( new_name - > name , name , sizeof ( new_name - > name ) ) ;
2005-06-26 20:55:24 +04:00
dbg ( " adding '%s' " , new_name - > name ) ;
list_add_tail ( & new_name - > node , & loop_name - > node ) ;
return 0 ;
}
int name_list_key_add ( struct list_head * name_list , const char * key , const char * value )
{
struct name_entry * loop_name ;
struct name_entry * new_name ;
list_for_each_entry ( loop_name , name_list , node ) {
if ( strncmp ( loop_name - > name , key , strlen ( key ) ) = = 0 ) {
dbg ( " key already present '%s', replace it " , loop_name - > name ) ;
snprintf ( loop_name - > name , sizeof ( loop_name - > name ) , " %s=%s " , key , value ) ;
loop_name - > name [ sizeof ( loop_name - > name ) - 1 ] = ' \0 ' ;
return 0 ;
}
}
new_name = malloc ( sizeof ( struct name_entry ) ) ;
if ( new_name = = NULL ) {
dbg ( " error malloc " ) ;
return - ENOMEM ;
}
snprintf ( new_name - > name , sizeof ( new_name - > name ) , " %s=%s " , key , value ) ;
new_name - > name [ sizeof ( new_name - > name ) - 1 ] = ' \0 ' ;
dbg ( " adding '%s' " , new_name - > name ) ;
2005-02-21 16:48:12 +03:00
list_add_tail ( & new_name - > node , & loop_name - > node ) ;
2005-03-04 23:33:57 +03:00
2004-03-27 12:21:46 +03:00
return 0 ;
}
2005-08-27 18:15:41 +04:00
void name_list_cleanup ( struct list_head * name_list )
{
struct name_entry * name_loop ;
struct name_entry * temp_loop ;
list_for_each_entry_safe ( name_loop , temp_loop , name_list , node ) {
list_del ( & name_loop - > node ) ;
free ( name_loop ) ;
}
}
2004-04-24 08:50:27 +04:00
/* calls function for every file found in specified directory */
2005-03-17 11:59:32 +03:00
int add_matching_files ( struct list_head * name_list , const char * dirname , const char * suffix )
2004-03-27 12:21:46 +03:00
{
struct dirent * ent ;
DIR * dir ;
char * ext ;
2005-03-17 11:59:32 +03:00
char filename [ PATH_SIZE ] ;
2004-03-27 12:21:46 +03:00
dbg ( " open directory '%s' " , dirname ) ;
dir = opendir ( dirname ) ;
if ( dir = = NULL ) {
dbg ( " unable to open '%s' " , dirname ) ;
return - 1 ;
}
while ( 1 ) {
ent = readdir ( dir ) ;
if ( ent = = NULL | | ent - > d_name [ 0 ] = = ' \0 ' )
break ;
if ( ( ent - > d_name [ 0 ] = = ' . ' ) | | ( ent - > d_name [ 0 ] = = COMMENT_CHARACTER ) )
continue ;
2005-03-17 11:59:32 +03:00
/* look for file matching with specified suffix */
2004-03-27 12:21:46 +03:00
ext = strrchr ( ent - > d_name , ' . ' ) ;
if ( ext = = NULL )
continue ;
if ( strcmp ( ext , suffix ) ! = 0 )
continue ;
dbg ( " put file '%s/%s' in list " , dirname , ent - > d_name ) ;
2005-03-17 11:59:32 +03:00
snprintf ( filename , sizeof ( filename ) , " %s/%s " , dirname , ent - > d_name ) ;
2005-03-07 06:29:43 +03:00
filename [ sizeof ( filename ) - 1 ] = ' \0 ' ;
2005-03-17 11:59:32 +03:00
name_list_add ( name_list , filename , 1 ) ;
2004-03-27 12:21:46 +03:00
}
closedir ( dir ) ;
return 0 ;
}