first cut at smbcontrol program. It currently allows syntax like:
[kai/samba.git] / source3 / utils / smbcontrol.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    program to send control messages to Samba processes
5    Copyright (C) Andrew Tridgell 1994-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #define NO_SYSLOG
23
24 #include "includes.h"
25
26 static struct {
27         char *name;
28         int value;
29 } msg_types[] = {
30         {"debug", MSG_DEBUG},
31         {"force-election", MSG_FORCE_ELECTION},
32         {"ping", MSG_PING},
33         {NULL, -1}
34 };
35
36 static void usage(void)
37 {
38         int i;
39         printf("Usage: smbcontrol <destination> <message-type> <parameters>\n\n");
40         printf("\t<destination> is one of \"nmbd\", \"smbd\" or a process ID\n");
41         printf("\t<message-type> is one of: ");
42         for (i=0; msg_types[i].name; i++) printf("%s, ", msg_types[i].name);
43         printf("\n");
44         exit(1);
45 }
46
47 static int pong_count;
48
49 /****************************************************************************
50 a useful function for testing the message system
51 ****************************************************************************/
52 void pong_function(int msg_type, pid_t src, void *buf, size_t len)
53 {
54         pong_count++;
55 }
56
57 /****************************************************************************
58 send a message to a named destination
59 ****************************************************************************/
60 static BOOL send_message(char *dest, int msg_type, void *buf, int len)
61 {
62         pid_t pid;
63
64         /* "smbd" is the only broadcast operation */
65         if (strequal(dest,"smbd")) {
66                 return message_send_all(msg_type, buf, len);
67         } else if (strequal(dest,"nmbd")) {
68                 pid = pidfile_pid(dest);
69                 if (pid == 0) {
70                         fprintf(stderr,"Can't find pid for nmbd\n");
71                         return False;
72                 }
73         } else {
74                 pid = atoi(dest);
75                 if (pid == 0) {
76                         fprintf(stderr,"Not a valid pid\n");
77                         return False;
78                 }               
79         } 
80
81         return message_send_pid(pid, msg_type, buf, len);
82 }
83
84 /****************************************************************************
85 evaluate a message type string
86 ****************************************************************************/
87 static int parse_type(char *mtype)
88 {
89         int i;
90         for (i=0;msg_types[i].name;i++) {
91                 if (strequal(mtype, msg_types[i].name)) return msg_types[i].value;
92         }
93         return -1;
94 }
95
96
97  int main(int argc, char *argv[])
98 {
99         char *dest;
100         int i, n, v;
101         pstring servicesf = CONFIGFILE;
102         int mtype;
103
104         TimeInit();
105         setup_logging(argv[0],True);
106         
107         charset_initialise();
108         lp_load(servicesf,False,False,False);
109
110         message_init();
111
112         if (argc < 3) usage();
113
114         dest = argv[1];
115         mtype = parse_type(argv[2]);
116         if (mtype == -1) {
117                 fprintf(stderr,"Couldn't resolve message type: %s\n", argv[2]);
118                 exit(1);
119         }
120
121         argc -= 2;
122         argv += 2;
123         
124         switch (mtype) {
125         case MSG_DEBUG:
126                 if (argc < 2) {
127                         fprintf(stderr,"MSG_DEBUG needs a parameter\n");
128                         exit(1);
129                 }
130                 v = atoi(argv[1]);
131                 send_message(dest, MSG_DEBUG, &v, sizeof(int));
132                 break;
133
134         case MSG_FORCE_ELECTION:
135                 if (!strequal(dest, "nmbd")) {
136                         fprintf(stderr,"force-election can only be sent to nmbd\n");
137                         exit(1);
138                 }
139                 send_message(dest, MSG_FORCE_ELECTION, NULL, 0);
140                 break;
141
142         case MSG_PING:
143                 message_register(MSG_PONG, pong_function);
144                 n = atoi(argv[1]);
145                 for (i=0;i<n;i++) {
146                         send_message(dest, MSG_PING, NULL, 0);
147                 }
148                 while (pong_count < n) message_dispatch();
149                 break;
150
151         }
152         
153         return (0);
154 }
155