2004-03-23 09:22:20 +03:00
/*
2008-09-10 04:40:42 +04:00
* Copyright ( C ) 2004 - 2008 Kay Sievers < kay . sievers @ vrfy . org >
2004-03-23 09:22:20 +03: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 .
2004-03-23 09:22:20 +03: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/>.
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>
2008-07-30 03:45:23 +04:00
# include <string.h>
2004-03-23 09:22:20 +03:00
# 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"
2008-09-06 17:45:31 +04:00
struct name_entry * name_list_add ( struct udev * udev , 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 ) {
2008-09-06 17:45:31 +04:00
dbg ( udev , " '%s' is already in the list \n " , 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 ;
2008-09-01 18:36:43 +04:00
memset ( name_new , 0x00 , sizeof ( struct name_entry ) ) ;
2008-09-10 20:59:42 +04:00
util_strlcpy ( name_new - > name , name , sizeof ( name_new - > name ) ) ;
2008-09-06 17:45:31 +04:00
dbg ( udev , " adding '%s' \n " , name_new - > name ) ;
2007-07-15 21:01:01 +04:00
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
}
2008-09-06 17:45:31 +04:00
struct name_entry * name_list_key_add ( struct udev * udev , 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 ;
2008-09-08 23:51:30 +04:00
size_t keylen = strlen ( key ) ;
2007-07-15 21:01:01 +04:00
list_for_each_entry ( name_loop , name_list , node ) {
2008-09-08 23:51:30 +04:00
if ( strncmp ( name_loop - > name , key , keylen ) ! = 0 )
continue ;
if ( name_loop - > name [ keylen ] ! = ' = ' )
continue ;
dbg ( udev , " key already present '%s', replace it \n " , 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 ;
2008-09-01 18:36:43 +04:00
memset ( name_new , 0x00 , sizeof ( struct name_entry ) ) ;
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 ' ;
2008-09-06 17:45:31 +04:00
dbg ( udev , " adding '%s' \n " , name_new - > name ) ;
2007-07-15 21:01:01 +04:00
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
}
2008-09-06 17:45:31 +04:00
int name_list_key_remove ( struct udev * udev , struct list_head * name_list , const char * key )
2007-04-25 03:52:00 +04:00
{
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 ;
}
2008-09-06 17:45:31 +04:00
void name_list_cleanup ( struct udev * udev , struct list_head * name_list )
2005-08-27 18:15:41 +04:00
{
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 ) ;
}
}
2008-09-06 17:45:31 +04:00
uid_t lookup_user ( struct udev * udev , const char * user )
2006-08-20 20:25:57 +04:00
{
struct passwd * pw ;
uid_t uid = 0 ;
errno = 0 ;
pw = getpwnam ( user ) ;
if ( pw = = NULL ) {
if ( errno = = 0 | | errno = = ENOENT | | errno = = ESRCH )
2008-09-06 17:45:31 +04:00
err ( udev , " specified user '%s' unknown \n " , user ) ;
2006-08-20 20:25:57 +04:00
else
2008-09-29 19:01:32 +04:00
err ( udev , " error resolving user '%s': %m \n " , user ) ;
2006-08-20 20:25:57 +04:00
} else
uid = pw - > pw_uid ;
return uid ;
}
2008-09-06 17:45:31 +04:00
extern gid_t lookup_group ( struct udev * udev , const char * group )
2006-08-20 20:25:57 +04:00
{
struct group * gr ;
gid_t gid = 0 ;
errno = 0 ;
gr = getgrnam ( group ) ;
if ( gr = = NULL ) {
if ( errno = = 0 | | errno = = ENOENT | | errno = = ESRCH )
2008-09-06 17:45:31 +04:00
err ( udev , " specified group '%s' unknown \n " , group ) ;
2006-08-20 20:25:57 +04:00
else
2008-09-29 19:01:32 +04:00
err ( udev , " error resolving group '%s': %m \n " , group ) ;
2006-08-20 20:25:57 +04:00
} else
gid = gr - > gr_gid ;
return gid ;
}