2000-09-13 11:07:17 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-09-13 11:07:17 +04:00
program to send control messages to Samba processes
Copyright ( C ) Andrew Tridgell 1994 - 1998
2002-01-09 11:27:15 +03:00
Copyright ( C ) 2001 , 2002 by Martin Pool
2002-07-15 14:35:28 +04:00
Copyright ( C ) Simo Sorce 2002
2000-09-13 11:07:17 +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 .
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 "includes.h"
2002-01-08 00:32:22 +03:00
extern BOOL AllowDebugChange ;
2000-09-13 11:07:17 +04:00
static struct {
char * name ;
int value ;
} msg_types [ ] = {
{ " debug " , MSG_DEBUG } ,
{ " force-election " , MSG_FORCE_ELECTION } ,
{ " ping " , MSG_PING } ,
2000-10-07 03:01:47 +04:00
{ " profile " , MSG_PROFILE } ,
2000-11-11 03:33:33 +03:00
{ " profilelevel " , MSG_REQ_PROFILELEVEL } ,
2000-10-07 03:01:47 +04:00
{ " debuglevel " , MSG_REQ_DEBUGLEVEL } ,
2002-07-15 14:35:28 +04:00
{ " printnotify " , MSG_PRINTER_NOTIFY2 } ,
2001-06-20 07:05:09 +04:00
{ " close-share " , MSG_SMB_FORCE_TDIS } ,
2001-08-28 10:38:11 +04:00
{ " samsync " , MSG_SMB_SAM_SYNC } ,
{ " samrepl " , MSG_SMB_SAM_REPL } ,
2001-12-21 07:28:03 +03:00
{ " pool-usage " , MSG_REQ_POOL_USAGE } ,
2002-01-09 11:27:15 +03:00
{ " dmalloc-mark " , MSG_REQ_DMALLOC_MARK } ,
{ " dmalloc-log-changed " , MSG_REQ_DMALLOC_LOG_CHANGED } ,
2002-03-29 16:49:48 +03:00
{ " shutdown " , MSG_SHUTDOWN } ,
2002-11-26 03:46:31 +03:00
{ " drvupgrade " , MSG_PRINTER_DRVUPGRADE } ,
2000-09-13 11:07:17 +04:00
{ NULL , - 1 }
} ;
2000-10-12 04:29:01 +04:00
time_t timeout_start ;
# define MAX_WAIT 10
2002-11-26 03:46:31 +03:00
/* we need these because we link to printing*.o */
void become_root ( void ) { }
void unbecome_root ( void ) { }
2000-09-30 00:08:00 +04:00
static void usage ( BOOL doexit )
2000-09-13 11:07:17 +04:00
{
int i ;
2000-09-30 00:08:00 +04:00
if ( doexit ) {
2001-09-21 17:37:52 +04:00
printf ( " Usage: smbcontrol -i -s configfile \n " ) ;
2000-09-30 00:08:00 +04:00
printf ( " smbcontrol <destination> <message-type> <parameters> \n \n " ) ;
} else {
printf ( " <destination> <message-type> <parameters> \n \n " ) ;
}
2000-09-13 11:07:17 +04:00
printf ( " \t <destination> is one of \" nmbd \" , \" smbd \" or a process ID \n " ) ;
2002-12-16 19:49:51 +03:00
printf ( " \t <message-type> is one of: \n " ) ;
2000-10-07 03:01:47 +04:00
for ( i = 0 ; msg_types [ i ] . name ; i + + )
2002-12-16 19:49:51 +03:00
printf ( " \t \t %s \n " , msg_types [ i ] . name ) ;
2000-09-13 11:07:17 +04:00
printf ( " \n " ) ;
2000-09-30 00:08:00 +04:00
if ( doexit ) exit ( 1 ) ;
2000-09-13 11:07:17 +04:00
}
static int pong_count ;
2000-10-07 03:01:47 +04:00
static BOOL got_level ;
static BOOL pong_registered = False ;
static BOOL debuglevel_registered = False ;
2000-11-11 03:33:33 +03:00
static BOOL profilelevel_registered = False ;
2001-12-21 07:28:03 +03:00
/**
* Wait for replies for up to @ p * max_secs seconds , or until @ p
2001-12-21 07:30:58 +03:00
* max_replies are received . max_replies may be NULL in which case it
* is ignored .
2001-12-21 07:28:03 +03:00
*
* @ note This is a pretty lame timeout ; all it means is that after
* max_secs we won ' t look for any more messages .
* */
static void wait_for_replies ( int max_secs , int * max_replies )
{
time_t timeout_end = time ( NULL ) + max_secs ;
2001-12-21 07:30:58 +03:00
while ( ( ! max_replies | | ( * max_replies ) - - > 0 )
& & ( time ( NULL ) < timeout_end ) ) {
2001-12-21 07:28:03 +03:00
message_dispatch ( ) ;
}
}
2000-10-07 03:01:47 +04:00
2000-09-13 11:07:17 +04:00
/****************************************************************************
a useful function for testing the message system
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void pong_function ( int msg_type , pid_t src , void * buf , size_t len )
{
pong_count + + ;
2001-04-28 02:42:10 +04:00
printf ( " PONG from PID %u \n " , ( unsigned int ) src ) ;
2000-10-07 03:01:47 +04:00
}
/****************************************************************************
Prints out the current Debug level returned by MSG_DEBUGLEVEL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void debuglevel_function ( int msg_type , pid_t src , void * buf , size_t len )
{
2002-11-13 02:20:50 +03:00
const char * levels = ( char * ) buf ;
2002-07-15 14:35:28 +04:00
pstring dbgcl ;
printf ( " Current debug levels of PID %u are: \n " , ( unsigned int ) src ) ;
while ( next_token ( & levels , dbgcl , " " , sizeof ( pstring ) ) )
printf ( " %s \n " , dbgcl ) ;
2000-10-07 03:01:47 +04:00
got_level = True ;
2000-09-13 11:07:17 +04:00
}
2000-11-11 03:33:33 +03:00
/****************************************************************************
Prints out the current Profile level returned by MSG_PROFILELEVEL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void profilelevel_function ( int msg_type , pid_t src , void * buf , size_t len )
{
int level ;
2001-04-13 23:12:06 +04:00
char * s = NULL ;
2000-11-11 03:33:33 +03:00
memcpy ( & level , buf , sizeof ( int ) ) ;
if ( level ) {
switch ( level ) {
case 1 :
s = " off " ;
break ;
case 3 :
s = " count only " ;
break ;
case 7 :
s = " count and time " ;
break ;
2002-01-10 09:32:01 +03:00
default :
s = " BOGUS " ;
break ;
2000-11-11 03:33:33 +03:00
}
2001-04-28 02:42:10 +04:00
printf ( " Profiling %s on PID %u \n " , s , ( unsigned int ) src ) ;
2000-11-11 03:33:33 +03:00
} else {
2001-04-28 02:42:10 +04:00
printf ( " Profiling not available on PID %u \n " , ( unsigned int ) src ) ;
2000-11-11 03:33:33 +03:00
}
got_level = True ;
}
2001-12-21 07:28:03 +03:00
/**
* Handle reply from POOL_USAGE .
* */
static void pool_usage_cb ( int msg_type , pid_t src_pid , void * buf , size_t len )
{
2002-01-03 08:36:21 +03:00
printf ( " Got POOL_USAGE reply from pid%u: \n %.*s " ,
2002-01-03 07:22:55 +03:00
( unsigned int ) src_pid , ( int ) len , ( const char * ) buf ) ;
2001-12-21 07:28:03 +03:00
}
/**
* Send a message to a named destination
*
* @ return False if an error occurred .
* */
2000-11-17 00:38:24 +03:00
static BOOL send_message ( char * dest , int msg_type , void * buf , int len , BOOL duplicates )
2000-09-13 11:07:17 +04:00
{
pid_t pid ;
/* "smbd" is the only broadcast operation */
if ( strequal ( dest , " smbd " ) ) {
2001-05-15 05:28:34 +04:00
TDB_CONTEXT * tdb ;
BOOL ret ;
2001-12-21 07:28:03 +03:00
int n_sent = 0 ;
2001-05-15 05:28:34 +04:00
2001-09-07 02:08:19 +04:00
tdb = tdb_open_log ( lock_path ( " connections.tdb " ) , 0 , TDB_DEFAULT , O_RDWR , 0 ) ;
2001-05-15 05:28:34 +04:00
if ( ! tdb ) {
fprintf ( stderr , " Failed to open connections database in send_message. \n " ) ;
return False ;
}
2001-12-21 07:28:03 +03:00
ret = message_send_all ( tdb , msg_type , buf , len , duplicates ,
& n_sent ) ;
DEBUG ( 10 , ( " smbcontrol/send_message: broadcast message to "
" %d processes \n " , n_sent ) ) ;
2001-05-15 05:28:34 +04:00
tdb_close ( tdb ) ;
return ret ;
2000-09-13 11:07:17 +04:00
} else if ( strequal ( dest , " nmbd " ) ) {
pid = pidfile_pid ( dest ) ;
if ( pid = = 0 ) {
fprintf ( stderr , " Can't find pid for nmbd \n " ) ;
return False ;
}
2000-11-17 04:20:03 +03:00
} else if ( strequal ( dest , " self " ) ) {
2002-03-14 04:53:04 +03:00
pid = sys_getpid ( ) ;
2000-09-13 11:07:17 +04:00
} else {
pid = atoi ( dest ) ;
if ( pid = = 0 ) {
fprintf ( stderr , " Not a valid pid \n " ) ;
return False ;
}
}
2001-12-21 07:28:03 +03:00
DEBUG ( 10 , ( " smbcontrol/send_message: send message to pid%d \n " , pid ) ) ;
2000-11-17 00:38:24 +03:00
return message_send_pid ( pid , msg_type , buf , len , duplicates ) ;
2000-09-13 11:07:17 +04:00
}
/****************************************************************************
evaluate a message type string
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int parse_type ( char * mtype )
{
int i ;
for ( i = 0 ; msg_types [ i ] . name ; i + + ) {
if ( strequal ( mtype , msg_types [ i ] . name ) ) return msg_types [ i ] . value ;
}
return - 1 ;
}
2002-01-09 11:27:15 +03:00
static void register_all ( void )
{
message_register ( MSG_POOL_USAGE , pool_usage_cb ) ;
}
2002-08-17 18:45:04 +04:00
/* This guy is here so we can link printing/notify.c to the smbcontrol
binary without having to pull in tons of other crap . */
TDB_CONTEXT * conn_tdb_ctx ( void )
{
static TDB_CONTEXT * tdb ;
if ( tdb )
return tdb ;
tdb = tdb_open_log ( lock_path ( " connections.tdb " ) , 0 , TDB_DEFAULT , O_RDONLY , 0 ) ;
if ( ! tdb )
DEBUG ( 3 , ( " Failed to open connections database in send_spoolss_notify2_msg \n " ) ) ;
return tdb ;
}
2002-01-09 11:27:15 +03:00
2000-09-30 00:08:00 +04:00
/****************************************************************************
do command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-11-21 01:55:46 +03:00
static BOOL do_command ( char * dest , char * msg_name , int iparams , char * * params )
2000-09-13 11:07:17 +04:00
{
int i , n , v ;
int mtype ;
2001-04-13 23:12:06 +04:00
BOOL retval = False ;
2002-11-26 03:46:31 +03:00
BOOL check_notify_msgs = False ;
2000-09-13 11:07:17 +04:00
2000-09-30 00:08:00 +04:00
mtype = parse_type ( msg_name ) ;
2000-09-13 11:07:17 +04:00
if ( mtype = = - 1 ) {
2000-09-30 00:08:00 +04:00
fprintf ( stderr , " Couldn't resolve message type: %s \n " , msg_name ) ;
return ( False ) ;
2000-09-13 11:07:17 +04:00
}
switch ( mtype ) {
2001-06-01 16:04:44 +04:00
case MSG_DEBUG : {
2002-07-15 14:35:28 +04:00
char * buf , * b ;
char * * p ;
int dim = 0 ;
2001-06-01 16:04:44 +04:00
2001-05-15 02:37:01 +04:00
if ( ! params | | ! params [ 0 ] ) {
2000-09-13 11:07:17 +04:00
fprintf ( stderr , " MSG_DEBUG needs a parameter \n " ) ;
2000-09-30 00:08:00 +04:00
return ( False ) ;
2000-09-13 11:07:17 +04:00
}
2001-02-12 19:18:02 +03:00
2002-07-15 14:35:28 +04:00
/* first pass retrieve total lenght */
for ( p = params ; p & & * p ; p + + )
dim + = ( strnlen ( * p , 1024 ) + 1 ) ; /* lenght + space */
b = buf = malloc ( dim ) ;
if ( ! buf ) {
fprintf ( stderr , " Out of memory! " ) ;
2001-02-12 19:18:02 +03:00
return ( False ) ;
2002-07-15 14:35:28 +04:00
}
/* now build a single string with all parameters */
for ( p = params ; p & & * p ; p + + ) {
int l = strnlen ( * p , 1024 ) ;
strncpy ( b , * p , l ) ;
b [ l ] = ' ' ;
b = b + l + 1 ;
}
b [ - 1 ] = ' \0 ' ;
send_message ( dest , MSG_DEBUG , buf , dim , False ) ;
free ( buf ) ;
2000-09-13 11:07:17 +04:00
break ;
2001-06-01 16:04:44 +04:00
}
2000-09-13 11:07:17 +04:00
2000-10-07 03:01:47 +04:00
case MSG_PROFILE :
2001-06-20 07:05:09 +04:00
if ( ! params | | ! params [ 0 ] ) {
2000-10-07 03:01:47 +04:00
fprintf ( stderr , " MSG_PROFILE needs a parameter \n " ) ;
return ( False ) ;
}
2001-02-12 19:18:02 +03:00
if ( strequal ( params [ 0 ] , " off " ) ) {
2000-10-07 03:01:47 +04:00
v = 0 ;
2001-02-12 19:18:02 +03:00
} else if ( strequal ( params [ 0 ] , " count " ) ) {
2000-10-07 03:01:47 +04:00
v = 1 ;
2001-02-12 19:18:02 +03:00
} else if ( strequal ( params [ 0 ] , " on " ) ) {
2000-10-11 09:31:39 +04:00
v = 2 ;
2001-02-12 19:18:02 +03:00
} else if ( strequal ( params [ 0 ] , " flush " ) ) {
2000-10-11 09:31:39 +04:00
v = 3 ;
2000-10-07 03:01:47 +04:00
} else {
fprintf ( stderr ,
2000-10-11 09:31:39 +04:00
" MSG_PROFILE parameter must be off, count, on, or flush \n " ) ;
2000-10-07 03:01:47 +04:00
return ( False ) ;
}
2000-11-17 00:38:24 +03:00
send_message ( dest , MSG_PROFILE , & v , sizeof ( int ) , False ) ;
2000-10-07 03:01:47 +04:00
break ;
2000-09-13 11:07:17 +04:00
case MSG_FORCE_ELECTION :
if ( ! strequal ( dest , " nmbd " ) ) {
fprintf ( stderr , " force-election can only be sent to nmbd \n " ) ;
2000-09-30 00:08:00 +04:00
return ( False ) ;
2000-09-13 11:07:17 +04:00
}
2000-11-17 00:38:24 +03:00
send_message ( dest , MSG_FORCE_ELECTION , NULL , 0 , False ) ;
2000-09-13 11:07:17 +04:00
break ;
2000-11-11 03:33:33 +03:00
case MSG_REQ_PROFILELEVEL :
if ( ! profilelevel_registered ) {
message_register ( MSG_PROFILELEVEL , profilelevel_function ) ;
profilelevel_registered = True ;
}
got_level = False ;
2000-11-17 00:38:24 +03:00
retval = send_message ( dest , MSG_REQ_PROFILELEVEL , NULL , 0 , True ) ;
2000-11-11 03:33:33 +03:00
if ( retval ) {
timeout_start = time ( NULL ) ;
while ( ! got_level ) {
message_dispatch ( ) ;
if ( ( time ( NULL ) - timeout_start ) > MAX_WAIT ) {
fprintf ( stderr , " profilelevel timeout \n " ) ;
break ;
}
}
}
break ;
2000-10-07 03:01:47 +04:00
case MSG_REQ_DEBUGLEVEL :
if ( ! debuglevel_registered ) {
message_register ( MSG_DEBUGLEVEL , debuglevel_function ) ;
debuglevel_registered = True ;
}
got_level = False ;
2000-11-17 00:38:24 +03:00
retval = send_message ( dest , MSG_REQ_DEBUGLEVEL , NULL , 0 , True ) ;
2000-10-12 04:29:01 +04:00
if ( retval ) {
timeout_start = time ( NULL ) ;
while ( ! got_level ) {
message_dispatch ( ) ;
if ( ( time ( NULL ) - timeout_start ) > MAX_WAIT ) {
fprintf ( stderr , " debuglevel timeout \n " ) ;
break ;
}
}
}
2000-10-07 03:01:47 +04:00
break ;
2002-07-15 14:35:28 +04:00
/* Send a notification message to a printer */
case MSG_PRINTER_NOTIFY2 : {
char * cmd ;
/* Read subcommand */
2001-06-20 07:05:09 +04:00
if ( ! params | | ! params [ 0 ] ) {
2002-07-15 14:35:28 +04:00
fprintf ( stderr , " Must specify subcommand: \n " ) ;
fprintf ( stderr , " \t queuepause <printername> \n " ) ;
fprintf ( stderr , " \t queueresume <printername> \n " ) ;
2002-08-17 18:45:04 +04:00
fprintf ( stderr , " \t jobpause <printername> <unix jobid> \n " ) ;
fprintf ( stderr , " \t jobresume <printername> <unix jobid> \n " ) ;
fprintf ( stderr , " \t jobdelete <printername> <unix jobid> \n " ) ;
2002-12-16 19:49:51 +03:00
fprintf ( stderr , " \t printer <printername> <comment|port|driver> <new value> \n " ) ;
2002-07-15 14:35:28 +04:00
return False ;
2000-11-11 01:07:57 +03:00
}
2002-02-26 06:12:09 +03:00
2002-07-15 14:35:28 +04:00
cmd = params [ 0 ] ;
2002-11-26 03:46:31 +03:00
check_notify_msgs = True ;
2002-07-15 14:35:28 +04:00
/* Pause a print queue */
if ( strequal ( cmd , " queuepause " ) ) {
if ( ! params [ 1 ] ) {
fprintf ( stderr , " queuepause command requires a printer name \n " ) ;
return False ;
}
notify_printer_status_byname ( params [ 1 ] , PRINTER_STATUS_PAUSED ) ;
break ;
2002-02-26 06:12:09 +03:00
}
2002-07-15 14:35:28 +04:00
/* Resume a print queue */
if ( strequal ( cmd , " queueresume " ) ) {
if ( ! params [ 1 ] ) {
fprintf ( stderr , " queueresume command requires a printer name \n " ) ;
return False ;
}
notify_printer_status_byname ( params [ 1 ] , PRINTER_STATUS_OK ) ;
break ;
}
/* Pause a print job */
if ( strequal ( cmd , " jobpause " ) ) {
int jobid ;
if ( ! params [ 1 ] | | ! params [ 2 ] ) {
fprintf ( stderr , " jobpause command requires a printer name and a jobid \n " ) ;
return False ;
}
jobid = atoi ( params [ 2 ] ) ;
notify_job_status_byname (
params [ 1 ] , jobid , JOB_STATUS_PAUSED ,
SPOOLSS_NOTIFY_MSG_UNIX_JOBID ) ;
2002-11-26 03:46:31 +03:00
break ;
2002-07-15 14:35:28 +04:00
}
/* Resume a print job */
if ( strequal ( cmd , " jobresume " ) ) {
int jobid ;
if ( ! params [ 1 ] | | ! params [ 2 ] ) {
fprintf ( stderr , " jobresume command requires a printer name and a jobid \n " ) ;
return False ;
}
jobid = atoi ( params [ 2 ] ) ;
notify_job_status_byname (
params [ 1 ] , jobid , JOB_STATUS_QUEUED ,
SPOOLSS_NOTIFY_MSG_UNIX_JOBID ) ;
2002-11-26 03:46:31 +03:00
break ;
2002-07-15 14:35:28 +04:00
}
/* Delete a print job */
if ( strequal ( cmd , " jobdelete " ) ) {
int jobid ;
if ( ! params [ 1 ] | | ! params [ 2 ] ) {
fprintf ( stderr , " jobdelete command requires a printer name and a jobid \n " ) ;
return False ;
}
jobid = atoi ( params [ 2 ] ) ;
notify_job_status_byname (
params [ 1 ] , jobid , JOB_STATUS_DELETING ,
SPOOLSS_NOTIFY_MSG_UNIX_JOBID ) ;
notify_job_status_byname (
params [ 1 ] , jobid , JOB_STATUS_DELETING |
JOB_STATUS_DELETED ,
SPOOLSS_NOTIFY_MSG_UNIX_JOBID ) ;
}
2002-11-29 05:58:59 +03:00
2002-11-26 03:46:31 +03:00
/* printer change notify */
if ( strequal ( cmd , " printer " ) ) {
int attribute = - 1 ;
if ( ! params [ 1 ] | | ! params [ 2 ] | | ! params [ 3 ] ) {
fprintf ( stderr , " printer command requires an and attribute name and value! \n " ) ;
fprintf ( stderr , " supported attributes: \n " ) ;
fprintf ( stderr , " \t comment: \n " ) ;
fprintf ( stderr , " \t port: \n " ) ;
fprintf ( stderr , " \t driver: \n " ) ;
return False ;
}
if ( strequal ( params [ 2 ] , " comment " ) )
attribute = PRINTER_NOTIFY_COMMENT ;
else if ( strequal ( params [ 2 ] , " port " ) )
attribute = PRINTER_NOTIFY_PORT_NAME ;
else if ( strequal ( params [ 2 ] , " driver " ) )
attribute = PRINTER_NOTIFY_DRIVER_NAME ;
if ( attribute = = - 1 ) {
fprintf ( stderr , " bad attribute! \n " ) ;
return False ;
}
notify_printer_byname ( params [ 1 ] , attribute , params [ 3 ] ) ;
break ;
}
2000-11-11 01:07:57 +03:00
break ;
2002-07-15 14:35:28 +04:00
}
2002-11-26 03:46:31 +03:00
2000-11-11 01:07:57 +03:00
2001-06-20 07:05:09 +04:00
case MSG_SMB_FORCE_TDIS :
if ( ! strequal ( dest , " smbd " ) ) {
fprintf ( stderr , " close-share can only be sent to smbd \n " ) ;
return ( False ) ;
}
if ( ! params | | ! params [ 0 ] ) {
fprintf ( stderr , " close-share needs a share name or '*' \n " ) ;
return ( False ) ;
}
retval = send_message ( dest , MSG_SMB_FORCE_TDIS , params [ 0 ] ,
strlen ( params [ 0 ] ) + 1 , False ) ;
break ;
2001-08-28 10:38:11 +04:00
case MSG_SMB_SAM_SYNC :
if ( ! strequal ( dest , " smbd " ) ) {
fprintf ( stderr , " samsync can only be sent to smbd \n " ) ;
return False ;
}
if ( params ) {
fprintf ( stderr , " samsync does not take any parameters \n " ) ;
return False ;
}
retval = send_message ( dest , MSG_SMB_SAM_SYNC , NULL , 0 , False ) ;
break ;
case MSG_SMB_SAM_REPL : {
uint32 seqnum ;
if ( ! strequal ( dest , " smbd " ) ) {
fprintf ( stderr , " sam repl can only be sent to smbd \n " ) ;
return False ;
}
if ( ! params | | ! params [ 0 ] ) {
fprintf ( stderr , " SAM_REPL needs a parameter \n " ) ;
return False ;
}
seqnum = atoi ( params [ 0 ] ) ;
retval = send_message ( dest , MSG_SMB_SAM_SYNC ,
( char * ) & seqnum , sizeof ( uint32 ) , False ) ;
break ;
}
2000-09-13 11:07:17 +04:00
case MSG_PING :
2000-10-07 03:01:47 +04:00
if ( ! pong_registered ) {
message_register ( MSG_PONG , pong_function ) ;
pong_registered = True ;
}
2001-06-20 07:05:09 +04:00
if ( ! params | | ! params [ 0 ] ) {
2000-09-30 00:08:00 +04:00
fprintf ( stderr , " MSG_PING needs a parameter \n " ) ;
return ( False ) ;
}
2001-02-12 19:18:02 +03:00
n = atoi ( params [ 0 ] ) ;
2000-10-07 03:01:47 +04:00
pong_count = 0 ;
2000-09-13 11:07:17 +04:00
for ( i = 0 ; i < n ; i + + ) {
2001-11-21 01:55:46 +03:00
if ( iparams > 1 )
retval = send_message ( dest , MSG_PING , params [ 1 ] , strlen ( params [ 1 ] ) + 1 , True ) ;
else
retval = send_message ( dest , MSG_PING , NULL , 0 , True ) ;
2001-12-21 07:28:03 +03:00
if ( retval = = False )
return False ;
2000-10-12 04:29:01 +04:00
}
2001-12-21 07:28:03 +03:00
wait_for_replies ( MAX_WAIT , & n ) ;
if ( n > 0 ) {
fprintf ( stderr , " PING timeout \n " ) ;
2000-09-13 11:07:17 +04:00
}
break ;
2001-12-21 07:28:03 +03:00
case MSG_REQ_POOL_USAGE :
if ( ! send_message ( dest , MSG_REQ_POOL_USAGE , NULL , 0 , True ) )
return False ;
2001-12-21 07:30:58 +03:00
wait_for_replies ( MAX_WAIT , NULL ) ;
2001-12-21 07:28:03 +03:00
break ;
2002-01-09 11:27:15 +03:00
case MSG_REQ_DMALLOC_LOG_CHANGED :
case MSG_REQ_DMALLOC_MARK :
if ( ! send_message ( dest , mtype , NULL , 0 , False ) )
return False ;
break ;
2002-03-29 16:49:48 +03:00
case MSG_SHUTDOWN :
if ( ! send_message ( dest , MSG_SHUTDOWN , NULL , 0 , False ) )
return False ;
break ;
2002-09-25 19:19:00 +04:00
case MSG_PRINTER_DRVUPGRADE :
if ( ! send_message ( dest , MSG_PRINTER_DRVUPGRADE , params [ 0 ] , 0 , False ) )
return False ;
break ;
2000-09-13 11:07:17 +04:00
}
2001-12-21 07:28:03 +03:00
2002-11-26 03:46:31 +03:00
/* check if we have any pending print notify messages */
if ( check_notify_msgs )
print_notify_send_messages ( ) ;
2000-09-30 00:08:00 +04:00
return ( True ) ;
}
int main ( int argc , char * argv [ ] )
{
int opt ;
char temp [ 255 ] ;
extern int optind ;
BOOL interactive = False ;
2002-01-08 00:32:22 +03:00
AllowDebugChange = False ;
DEBUGLEVEL = 0 ;
2000-09-30 00:08:00 +04:00
setup_logging ( argv [ 0 ] , True ) ;
if ( argc < 2 ) usage ( True ) ;
2001-09-21 17:37:52 +04:00
while ( ( opt = getopt ( argc , argv , " is: " ) ) ! = EOF ) {
2000-09-30 00:08:00 +04:00
switch ( opt ) {
case ' i ' :
interactive = True ;
break ;
2001-09-21 17:37:52 +04:00
case ' s ' :
2001-11-19 05:49:53 +03:00
pstrcpy ( dyn_CONFIGFILE , optarg ) ;
2001-09-21 17:37:52 +04:00
break ;
2000-09-30 00:08:00 +04:00
default :
printf ( " Unknown option %c (%d) \n " , ( char ) opt , opt ) ;
usage ( True ) ;
}
}
2001-11-19 05:49:53 +03:00
lp_load ( dyn_CONFIGFILE , False , False , False ) ;
2001-09-21 17:37:52 +04:00
if ( ! message_init ( ) ) exit ( 1 ) ;
2000-09-30 00:08:00 +04:00
argc - = optind ;
argv = & argv [ optind ] ;
2002-01-09 11:27:15 +03:00
register_all ( ) ;
2000-09-30 00:08:00 +04:00
if ( ! interactive ) {
if ( argc < 2 ) usage ( True ) ;
2001-12-21 07:33:28 +03:00
/* Need to invert sense of return code -- samba
* routines mostly return True = = 1 for success , but
* shell needs 0. */
return ! do_command ( argv [ 0 ] , argv [ 1 ] , argc - 2 , argc > 2 ? & argv [ 2 ] : 0 ) ;
2000-09-30 00:08:00 +04:00
}
while ( True ) {
2001-11-21 01:55:46 +03:00
char * myargv [ 4 ] ;
2000-09-30 00:08:00 +04:00
int myargc ;
printf ( " smbcontrol> " ) ;
2000-10-10 09:05:35 +04:00
if ( ! fgets ( temp , sizeof ( temp ) - 1 , stdin ) ) break ;
2000-09-30 00:08:00 +04:00
myargc = 0 ;
2001-11-21 01:55:46 +03:00
while ( ( myargc < 4 ) & &
2000-10-10 09:05:35 +04:00
( myargv [ myargc ] = strtok ( myargc ? NULL : temp , " \t \n " ) ) ) {
2000-09-30 00:08:00 +04:00
myargc + + ;
}
if ( ! myargc ) break ;
2000-10-12 21:58:40 +04:00
if ( strequal ( myargv [ 0 ] , " q " ) ) break ;
2000-09-30 00:08:00 +04:00
if ( myargc < 2 )
usage ( False ) ;
2001-11-21 01:55:46 +03:00
else if ( ! do_command ( myargv [ 0 ] , myargv [ 1 ] , myargc - 2 , myargc > 2 ? & myargv [ 2 ] : 0 ) )
2000-09-30 00:08:00 +04:00
usage ( False ) ;
}
return ( 0 ) ;
2000-09-13 11:07:17 +04:00
}