From 7be9a4fd4c044fa98c434bbdbf0f8229f1101bbb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Sep 2000 07:07:17 +0000 Subject: [PATCH] first cut at smbcontrol program. It currently allows syntax like: smbcontrol nmbd debug 7 smbcontrol smbd debug 9 smbcontrol 3278 debug 1 smbcontrol nmbd force-election (This used to be commit 5f91c24636f5d82486f22c10bc55e060f9c518bf) --- source3/Makefile.in | 8 +- source3/include/proto.h | 3 + source3/lib/messages.c | 43 ++++++++++ source3/utils/msgtest.c | 18 +---- source3/utils/smbcontrol.c | 155 +++++++++++++++++++++++++++++++++++++ 5 files changed, 209 insertions(+), 18 deletions(-) create mode 100644 source3/utils/smbcontrol.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 7d242ea569b..716afcd927c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -83,7 +83,7 @@ FLAGS = $(ISA) $(FLAGS5) $(PASSWD_FLAGS) FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS) SPROGS = bin/smbd bin/nmbd bin/swat -PROGS1 = bin/smbclient bin/smbspool bin/testparm bin/testprns bin/smbstatus @RUNPROG@ +PROGS1 = bin/smbclient bin/smbspool bin/testparm bin/testprns bin/smbstatus bin/smbcontrol @RUNPROG@ PROGS2 = bin/smbpasswd bin/make_smbcodepage bin/make_unicodemap bin/rpcclient @WRAP@ @WRAP32@ MPROGS = @MPROGS@ PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup bin/make_printerdef @@ -226,7 +226,7 @@ MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o $(PARAM_OBJ) \ STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) -MSGTEST_OBJ = utils/msgtest.o $(LOCKING_OBJ) $(PARAM_OBJ) \ +SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) TESTPARM_OBJ = utils/testparm.o \ @@ -470,9 +470,9 @@ bin/smbstatus: $(STATUS_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(LIBS) -bin/msgtest: $(MSGTEST_OBJ) bin/.dummy +bin/smbcontrol: $(SMBCONTROL_OBJ) bin/.dummy @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS) + @$(CC) $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(LDFLAGS) $(LIBS) bin/smbpasswd: $(SMBPASSWD_OBJ) bin/.dummy @echo Linking $@ diff --git a/source3/include/proto.h b/source3/include/proto.h index 4fc539ef6eb..2d04cb2a93b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -152,11 +152,14 @@ void mdfour(unsigned char *out, unsigned char *in, int n); /*The following definitions come from lib/messages.c */ +void ping_message(int msg_type, pid_t src, void *buf, size_t len); BOOL message_init(void); BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len); void message_dispatch(void); void message_register(int msg_type, void (*fn)(int msg_type, pid_t pid, void *buf, size_t len)); +void message_deregister(int msg_type); +BOOL message_send_all(int msg_type, void *buf, size_t len); /*The following definitions come from lib/ms_fnmatch.c */ diff --git a/source3/lib/messages.c b/source3/lib/messages.c index 939bf36004f..4153c21c23c 100644 --- a/source3/lib/messages.c +++ b/source3/lib/messages.c @@ -304,3 +304,46 @@ void message_deregister(int msg_type) } } } + +static struct { + int msg_type; + void *buf; + size_t len; +} msg_all; + +/**************************************************************************** +send one of the messages for the broadcast +****************************************************************************/ +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +{ + struct connections_data crec; + + memcpy(&crec, dbuf.dptr, sizeof(crec)); + + message_send_pid(crec.pid, msg_all.msg_type, msg_all.buf, msg_all.len); + return 0; +} + +/**************************************************************************** +this is a useful function for sending messages to all smbd processes. +It isn't very efficient, but should be OK for the sorts of applications that +use it. When we need efficient broadcast we can add it. +****************************************************************************/ +BOOL message_send_all(int msg_type, void *buf, size_t len) +{ + TDB_CONTEXT *tdb; + + tdb = tdb_open(lock_path("connections.tdb"), 0, 0, O_RDONLY, 0); + if (!tdb) { + DEBUG(2,("Failed to open connections database in message_send_all\n")); + return False; + } + + msg_all.msg_type = msg_type; + msg_all.buf = buf; + msg_all.len = len; + + tdb_traverse(tdb, traverse_fn, NULL); + tdb_close(tdb); + return True; +} diff --git a/source3/utils/msgtest.c b/source3/utils/msgtest.c index 4821aef80bf..858166e697f 100644 --- a/source3/utils/msgtest.c +++ b/source3/utils/msgtest.c @@ -1,8 +1,7 @@ /* Unix SMB/Netbios implementation. - Version 1.9. - status reporting - Copyright (C) Andrew Tridgell 1994-1998 + Version 3.0 + Copyright (C) Andrew Tridgell 2000 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 @@ -17,19 +16,10 @@ 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 02139, USA. - - Revision History: - - 12 aug 96: Erik.Devriendt@te6.siemens.be - added support for shared memory implementation of share mode locking - - 21-Jul-1998: rsharpe@ns.aus.com (Richard Sharpe) - Added -L (locks only) -S (shares only) flags and code - */ /* - * This program reports current SMB connections + test code for internal messaging */ #define NO_SYSLOG @@ -71,7 +61,7 @@ void pong_message(int msg_type, pid_t src, void *buf, size_t len) message_send_pid(pid, MSG_PING, NULL, 0); } - while (pong_count < n) { + while (pong_count < i) { message_dispatch(); msleep(1); } diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c new file mode 100644 index 00000000000..b31b53473c4 --- /dev/null +++ b/source3/utils/smbcontrol.c @@ -0,0 +1,155 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + program to send control messages to Samba processes + Copyright (C) Andrew Tridgell 1994-1998 + + 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 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +static struct { + char *name; + int value; +} msg_types[] = { + {"debug", MSG_DEBUG}, + {"force-election", MSG_FORCE_ELECTION}, + {"ping", MSG_PING}, + {NULL, -1} +}; + +static void usage(void) +{ + int i; + printf("Usage: smbcontrol \n\n"); + printf("\t is one of \"nmbd\", \"smbd\" or a process ID\n"); + printf("\t is one of: "); + for (i=0; msg_types[i].name; i++) printf("%s, ", msg_types[i].name); + printf("\n"); + exit(1); +} + +static int pong_count; + +/**************************************************************************** +a useful function for testing the message system +****************************************************************************/ +void pong_function(int msg_type, pid_t src, void *buf, size_t len) +{ + pong_count++; +} + +/**************************************************************************** +send a message to a named destination +****************************************************************************/ +static BOOL send_message(char *dest, int msg_type, void *buf, int len) +{ + pid_t pid; + + /* "smbd" is the only broadcast operation */ + if (strequal(dest,"smbd")) { + return message_send_all(msg_type, buf, len); + } else if (strequal(dest,"nmbd")) { + pid = pidfile_pid(dest); + if (pid == 0) { + fprintf(stderr,"Can't find pid for nmbd\n"); + return False; + } + } else { + pid = atoi(dest); + if (pid == 0) { + fprintf(stderr,"Not a valid pid\n"); + return False; + } + } + + return message_send_pid(pid, msg_type, buf, len); +} + +/**************************************************************************** +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; +} + + + int main(int argc, char *argv[]) +{ + char *dest; + int i, n, v; + pstring servicesf = CONFIGFILE; + int mtype; + + TimeInit(); + setup_logging(argv[0],True); + + charset_initialise(); + lp_load(servicesf,False,False,False); + + message_init(); + + if (argc < 3) usage(); + + dest = argv[1]; + mtype = parse_type(argv[2]); + if (mtype == -1) { + fprintf(stderr,"Couldn't resolve message type: %s\n", argv[2]); + exit(1); + } + + argc -= 2; + argv += 2; + + switch (mtype) { + case MSG_DEBUG: + if (argc < 2) { + fprintf(stderr,"MSG_DEBUG needs a parameter\n"); + exit(1); + } + v = atoi(argv[1]); + send_message(dest, MSG_DEBUG, &v, sizeof(int)); + break; + + case MSG_FORCE_ELECTION: + if (!strequal(dest, "nmbd")) { + fprintf(stderr,"force-election can only be sent to nmbd\n"); + exit(1); + } + send_message(dest, MSG_FORCE_ELECTION, NULL, 0); + break; + + case MSG_PING: + message_register(MSG_PONG, pong_function); + n = atoi(argv[1]); + for (i=0;i