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 . ,
2006-08-28 02:29:11 +04:00
* 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2004-03-23 09:22:20 +03:00
*
*/
# 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>
2006-08-20 20:25:57 +04:00
# include <pwd.h>
# include <grp.h>
# include <sys/types.h>
2004-11-13 14:36:47 +03:00
# include <sys/utsname.h>
2004-03-23 09:22:20 +03:00
# include "udev.h"
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 ;
}
2007-07-14 22:43:01 +04:00
struct name_entry * name_list_add ( struct list_head * name_list , const char * name , int sort )
2004-03-27 12:21:46 +03:00
{
2007-07-15 21:01:01 +04:00
struct name_entry * name_loop ;
struct name_entry * name_new ;
2005-02-21 16:48:12 +03:00
2007-07-15 21:01:01 +04:00
/* avoid duplicate entries */
list_for_each_entry ( name_loop , name_list , node ) {
if ( strcmp ( name_loop - > name , name ) = = 0 ) {
2005-02-21 16:48:12 +03:00
dbg ( " '%s' is already in the list " , name ) ;
2007-07-15 21:01:01 +04:00
return name_loop ;
2004-03-27 12:21:46 +03:00
}
}
2005-06-26 20:55:24 +04:00
if ( sort )
2007-07-15 21:01:01 +04:00
list_for_each_entry ( name_loop , name_list , node ) {
if ( strcmp ( name_loop - > name , name ) > 0 )
2005-06-26 20:55:24 +04:00
break ;
}
2007-07-15 21:01:01 +04:00
name_new = malloc ( sizeof ( struct name_entry ) ) ;
if ( name_new = = NULL )
2006-04-15 21:32:05 +04:00
return NULL ;
2004-03-27 12:21:46 +03:00
2007-07-15 21:01:01 +04:00
strlcpy ( name_new - > name , name , sizeof ( name_new - > name ) ) ;
dbg ( " adding '%s' " , name_new - > name ) ;
list_add_tail ( & name_new - > node , & name_loop - > node ) ;
2005-06-26 20:55:24 +04:00
2007-07-15 21:01:01 +04:00
return name_new ;
2005-06-26 20:55:24 +04:00
}
2007-07-14 22:43:01 +04:00
struct name_entry * name_list_key_add ( struct list_head * name_list , const char * key , const char * value )
2005-06-26 20:55:24 +04:00
{
2007-07-15 21:01:01 +04:00
struct name_entry * name_loop ;
struct name_entry * name_new ;
list_for_each_entry ( name_loop , name_list , node ) {
if ( strncmp ( name_loop - > name , key , strlen ( key ) ) = = 0 ) {
dbg ( " key already present '%s', replace it " , name_loop - > name ) ;
snprintf ( name_loop - > name , sizeof ( name_loop - > name ) , " %s=%s " , key , value ) ;
name_loop - > name [ sizeof ( name_loop - > name ) - 1 ] = ' \0 ' ;
return name_loop ;
2005-06-26 20:55:24 +04:00
}
}
2007-07-15 21:01:01 +04:00
name_new = malloc ( sizeof ( struct name_entry ) ) ;
if ( name_new = = NULL )
2006-04-15 21:32:05 +04:00
return NULL ;
2005-06-26 20:55:24 +04:00
2007-07-15 21:01:01 +04:00
snprintf ( name_new - > name , sizeof ( name_new - > name ) , " %s=%s " , key , value ) ;
name_new - > name [ sizeof ( name_new - > name ) - 1 ] = ' \0 ' ;
dbg ( " adding '%s' " , name_new - > name ) ;
list_add_tail ( & name_new - > node , & name_loop - > node ) ;
2005-03-04 23:33:57 +03:00
2007-07-15 21:01:01 +04:00
return name_new ;
2004-03-27 12:21:46 +03:00
}
2007-04-25 03:52:00 +04:00
int name_list_key_remove ( struct list_head * name_list , const char * key )
{
struct name_entry * name_loop ;
2007-07-15 21:01:01 +04:00
struct name_entry * name_tmp ;
2007-04-25 03:52:00 +04:00
size_t keylen = strlen ( key ) ;
int retval = 0 ;
2007-07-15 21:01:01 +04:00
list_for_each_entry_safe ( name_loop , name_tmp , name_list , node ) {
2007-04-25 03:52:00 +04:00
if ( strncmp ( name_loop - > name , key , keylen ) ! = 0 )
continue ;
if ( name_loop - > name [ keylen ] ! = ' = ' )
continue ;
list_del ( & name_loop - > node ) ;
free ( name_loop ) ;
retval = 1 ;
break ;
}
return retval ;
}
2005-08-27 18:15:41 +04:00
void name_list_cleanup ( struct list_head * name_list )
{
struct name_entry * name_loop ;
2007-07-15 21:01:01 +04:00
struct name_entry * name_tmp ;
2005-08-27 18:15:41 +04:00
2007-07-15 21:01:01 +04:00
list_for_each_entry_safe ( name_loop , name_tmp , name_list , node ) {
2005-08-27 18:15:41 +04:00
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 ;
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 ) {
2005-11-07 20:52:03 +03:00
err ( " unable to open '%s': %s " , dirname , strerror ( errno ) ) ;
2004-03-27 12:21:46 +03:00
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 */
2006-12-08 11:48:53 +03:00
if ( suffix ! = NULL ) {
const char * ext ;
ext = strrchr ( ent - > d_name , ' . ' ) ;
if ( ext = = NULL )
continue ;
if ( strcmp ( ext , suffix ) ! = 0 )
continue ;
}
dbg ( " put file '%s/%s' into list " , dirname , ent - > d_name ) ;
2004-03-27 12:21:46 +03:00
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 ;
}
2006-08-20 20:25:57 +04:00
uid_t lookup_user ( const char * user )
{
struct passwd * pw ;
uid_t uid = 0 ;
errno = 0 ;
pw = getpwnam ( user ) ;
if ( pw = = NULL ) {
if ( errno = = 0 | | errno = = ENOENT | | errno = = ESRCH )
2006-09-16 18:35:52 +04:00
err ( " specified user '%s' unknown " , user ) ;
2006-08-20 20:25:57 +04:00
else
err ( " error resolving user '%s': %s " , user , strerror ( errno ) ) ;
} else
uid = pw - > pw_uid ;
return uid ;
}
extern gid_t lookup_group ( const char * group )
{
struct group * gr ;
gid_t gid = 0 ;
errno = 0 ;
gr = getgrnam ( group ) ;
if ( gr = = NULL ) {
if ( errno = = 0 | | errno = = ENOENT | | errno = = ESRCH )
2006-09-16 18:35:52 +04:00
err ( " specified group '%s' unknown " , group ) ;
2006-08-20 20:25:57 +04:00
else
err ( " error resolving group '%s': %s " , group , strerror ( errno ) ) ;
} else
gid = gr - > gr_gid ;
return gid ;
}