2005-06-05 06:41:09 +04:00
/*
2006-08-21 04:38:20 +04:00
* Copyright ( C ) 2005 - 2006 Kay Sievers < kay . sievers @ vrfy . org >
2005-06-05 06:41:09 +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 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 .
2005-06-05 06:41:09 +04:00
*
*/
# include <time.h>
# include <errno.h>
# include <stdio.h>
# include <stdlib.h>
# include <stddef.h>
# include <string.h>
# include <unistd.h>
2006-05-01 22:36:21 +04:00
# include <sys/types.h>
# include <sys/socket.h>
# include <sys/wait.h>
# include <sys/un.h>
2005-06-05 06:41:09 +04:00
# include "udev.h"
# include "udevd.h"
static int sock = - 1 ;
2005-10-27 22:32:07 +04:00
static int udev_log = 0 ;
2005-06-05 06:41:09 +04:00
2007-11-08 19:51:59 +03:00
int udevcontrol ( int argc , char * argv [ ] , char * envp [ ] )
2005-06-05 06:41:09 +04:00
{
2006-08-05 15:22:44 +04:00
static struct udevd_ctrl_msg ctrl_msg ;
2005-06-05 06:41:09 +04:00
struct sockaddr_un saddr ;
socklen_t addrlen ;
2005-06-16 03:58:47 +04:00
const char * env ;
2007-04-27 00:52:20 +04:00
const char * arg ;
2005-06-16 05:22:27 +04:00
const char * val ;
int * intval ;
2005-06-05 06:41:09 +04:00
int retval = 1 ;
2005-06-16 03:58:47 +04:00
env = getenv ( " UDEV_LOG " ) ;
if ( env )
2005-10-27 22:32:07 +04:00
udev_log = log_priority ( env ) ;
2005-06-16 03:58:47 +04:00
2005-06-05 06:41:09 +04:00
logging_init ( " udevcontrol " ) ;
dbg ( " version %s " , UDEV_VERSION ) ;
2005-08-11 22:34:24 +04:00
if ( argc < 2 ) {
fprintf ( stderr , " missing command \n \n " ) ;
2005-06-05 06:41:09 +04:00
goto exit ;
}
2006-08-05 15:22:44 +04:00
memset ( & ctrl_msg , 0x00 , sizeof ( struct udevd_ctrl_msg ) ) ;
strcpy ( ctrl_msg . magic , UDEVD_CTRL_MAGIC ) ;
2007-04-27 00:52:20 +04:00
arg = argv [ 1 ] ;
2007-11-09 21:30:12 +03:00
/* allow instructions passed as options */
if ( strncmp ( arg , " -- " , 2 ) = = 0 )
arg + = 2 ;
2007-04-27 00:52:20 +04:00
if ( ! strcmp ( arg , " stop_exec_queue " ) )
ctrl_msg . type = UDEVD_CTRL_STOP_EXEC_QUEUE ;
else if ( ! strcmp ( arg , " start_exec_queue " ) )
ctrl_msg . type = UDEVD_CTRL_START_EXEC_QUEUE ;
else if ( ! strcmp ( arg , " reload_rules " ) )
ctrl_msg . type = UDEVD_CTRL_RELOAD_RULES ;
else if ( ! strncmp ( arg , " log_priority= " , strlen ( " log_priority= " ) ) ) {
intval = ( int * ) ctrl_msg . buf ;
val = & arg [ strlen ( " log_priority= " ) ] ;
ctrl_msg . type = UDEVD_CTRL_SET_LOG_LEVEL ;
* intval = log_priority ( val ) ;
info ( " send log_priority=%i " , * intval ) ;
} else if ( ! strncmp ( arg , " max_childs= " , strlen ( " max_childs= " ) ) ) {
char * endp ;
int count ;
intval = ( int * ) ctrl_msg . buf ;
val = & arg [ strlen ( " max_childs= " ) ] ;
ctrl_msg . type = UDEVD_CTRL_SET_MAX_CHILDS ;
count = strtoul ( val , & endp , 0 ) ;
if ( endp [ 0 ] ! = ' \0 ' | | count < 1 ) {
fprintf ( stderr , " invalid number \n " ) ;
goto exit ;
}
* intval = count ;
info ( " send max_childs=%i " , * intval ) ;
} else if ( ! strncmp ( arg , " max_childs_running= " , strlen ( " max_childs_running= " ) ) ) {
char * endp ;
int count ;
intval = ( int * ) ctrl_msg . buf ;
val = & arg [ strlen ( " max_childs_running= " ) ] ;
ctrl_msg . type = UDEVD_CTRL_SET_MAX_CHILDS_RUNNING ;
count = strtoul ( val , & endp , 0 ) ;
if ( endp [ 0 ] ! = ' \0 ' | | count < 1 ) {
fprintf ( stderr , " invalid number \n " ) ;
2006-07-03 03:03:53 +04:00
goto exit ;
2007-04-27 00:52:20 +04:00
}
* intval = count ;
info ( " send max_childs_running=%i " , * intval ) ;
} else if ( ! strncmp ( arg , " env " , strlen ( " env " ) ) ) {
val = argv [ 2 ] ;
if ( val = = NULL ) {
fprintf ( stderr , " missing key \n " ) ;
2006-07-03 03:03:53 +04:00
goto exit ;
2005-08-11 22:34:24 +04:00
}
2007-04-27 00:52:20 +04:00
ctrl_msg . type = UDEVD_CTRL_ENV ;
strlcpy ( ctrl_msg . buf , val , sizeof ( ctrl_msg . buf ) ) ;
info ( " send env '%s' " , val ) ;
2007-11-09 21:30:12 +03:00
} else if ( strcmp ( arg , " help " ) = = 0 | | strcmp ( arg , " -h " ) = = 0 ) {
2007-11-08 19:51:59 +03:00
printf ( " Usage: udevadm control COMMAND \n "
2007-11-09 21:30:12 +03:00
" --log_priority=<level> set the udev log level for the daemon \n "
" --stop_exec_queue keep udevd from executing events, queue only \n "
" --start_exec_queue execute events, flush queue \n "
" --reload_rules reloads the rules files \n "
" --env <var>=<value> set a global environment variable \n "
" --max_childs=<N> maximum number of childs \n "
" --max_childs_running=<N> maximum number of childs running at the same time \n "
" --help print this help text \n \n " ) ;
2007-04-27 00:52:20 +04:00
goto exit ;
} else {
fprintf ( stderr , " unrecognized command '%s' \n " , arg ) ;
goto exit ;
2005-08-11 22:34:24 +04:00
}
if ( getuid ( ) ! = 0 ) {
2006-08-21 04:38:20 +04:00
fprintf ( stderr , " root privileges required \n " ) ;
2006-07-03 03:03:53 +04:00
goto exit ;
2005-06-05 06:41:09 +04:00
}
sock = socket ( AF_LOCAL , SOCK_DGRAM , 0 ) ;
if ( sock = = - 1 ) {
2005-11-07 20:44:18 +03:00
err ( " error getting socket: %s " , strerror ( errno ) ) ;
2005-06-05 06:41:09 +04:00
goto exit ;
}
memset ( & saddr , 0x00 , sizeof ( struct sockaddr_un ) ) ;
saddr . sun_family = AF_LOCAL ;
/* use abstract namespace for socket path */
2006-08-05 15:22:44 +04:00
strcpy ( & saddr . sun_path [ 1 ] , UDEVD_CTRL_SOCK_PATH ) ;
2005-06-05 06:41:09 +04:00
addrlen = offsetof ( struct sockaddr_un , sun_path ) + strlen ( saddr . sun_path + 1 ) + 1 ;
2006-08-05 15:22:44 +04:00
retval = sendto ( sock , & ctrl_msg , sizeof ( ctrl_msg ) , 0 , ( struct sockaddr * ) & saddr , addrlen ) ;
2005-06-14 00:38:42 +04:00
if ( retval = = - 1 ) {
2005-11-07 20:44:18 +03:00
err ( " error sending message: %s " , strerror ( errno ) ) ;
2005-06-14 00:38:42 +04:00
retval = 1 ;
} else {
2006-08-05 15:22:44 +04:00
dbg ( " sent message type=0x%02x, %u bytes sent " , ctrl_msg . type , retval ) ;
2005-06-14 00:38:42 +04:00
retval = 0 ;
}
2005-06-05 06:41:09 +04:00
close ( sock ) ;
exit :
logging_close ( ) ;
return retval ;
}