/* Send a message to a destination pid. Zero means broadcast smbd. */
-static BOOL send_message(pid_t pid, int msg_type, void *buf, int len,
+static BOOL send_message(struct process_id pid, int msg_type,
+ const void *buf, int len,
BOOL duplicates)
{
TDB_CONTEXT *tdb;
if (!message_init())
return False;
- if (pid != 0)
+ if (procid_to_pid(&pid) != 0)
return message_send_pid(pid, msg_type, buf, len, duplicates);
tdb = tdb_open_log(lock_path("connections.tdb"), 0,
} while (timeout - (time(NULL) - start_time) > 0);
}
+/* Message handler callback that displays the PID and a string on stdout */
+
+static void print_pid_string_cb(int msg_type, struct process_id pid, void *buf, size_t len)
+{
+ printf("PID %u: %.*s", (unsigned int)procid_to_pid(&pid),
+ (int)len, (const char *)buf);
+ num_replies++;
+}
+
/* Message handler callback that displays a string on stdout */
-static void print_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void print_string_cb(int msg_type, struct process_id pid,
+ void *buf, size_t len)
{
printf("%.*s", (int)len, (const char *)buf);
num_replies++;
/* Send no message. Useful for testing. */
-static BOOL do_noop(const pid_t pid, const int argc, char **argv)
+static BOOL do_noop(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> noop\n");
/* Send a debug string */
-static BOOL do_debug(const pid_t pid, const int argc, char **argv)
+static BOOL do_debug(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> debug "
/* Force a browser election */
-static BOOL do_election(const pid_t pid, const int argc, char **argv)
+static BOOL do_election(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> force-election\n");
/* Ping a samba daemon process */
-static void pong_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void pong_cb(int msg_type, struct process_id pid, void *buf, size_t len)
{
- printf("PONG from pid %u\n", (unsigned int)pid);
+ char *src_string = procid_str(NULL, &pid);
+ printf("PONG from pid %s\n", src_string);
+ talloc_free(src_string);
num_replies++;
}
-static BOOL do_ping(const pid_t pid, const int argc, char **argv)
+static BOOL do_ping(const struct process_id pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> ping\n");
message_register(MSG_PONG, pong_cb);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
/* Set profiling options */
-static BOOL do_profile(const pid_t pid, const int argc, char **argv)
+static BOOL do_profile(const struct process_id pid,
+ const int argc, const char **argv)
{
int v;
/* Return the profiling level */
-static void profilelevel_cb(int msg_type, pid_t pid, void *buf, size_t len)
+static void profilelevel_cb(int msg_type, struct process_id pid, void *buf, size_t len)
{
int level;
const char *s;
num_replies++;
if (len != sizeof(int)) {
- fprintf(stderr, "invalid message length %d returned\n", len);
+ fprintf(stderr, "invalid message length %ld returned\n",
+ (unsigned long)len);
return;
}
break;
}
- printf("Profiling %s on pid %u\n",s,(unsigned int)pid);
+ printf("Profiling %s on pid %u\n",s,(unsigned int)procid_to_pid(&pid));
}
-static void profilelevel_rqst(int msg_type, pid_t pid, void *buf, size_t len)
+static void profilelevel_rqst(int msg_type, struct process_id pid,
+ void *buf, size_t len)
{
int v = 0;
send_message(pid, MSG_PROFILELEVEL, &v, sizeof(int), False);
}
-static BOOL do_profilelevel(const pid_t pid, const int argc, char **argv)
+static BOOL do_profilelevel(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> profilelevel\n");
message_register(MSG_PROFILELEVEL, profilelevel_cb);
message_register(MSG_REQ_PROFILELEVEL, profilelevel_rqst);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
/* Display debug level settings */
-static BOOL do_debuglevel(const pid_t pid, const int argc, char **argv)
+static BOOL do_debuglevel(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> debuglevel\n");
if (!send_message(pid, MSG_REQ_DEBUGLEVEL, NULL, 0, False))
return False;
- message_register(MSG_DEBUGLEVEL, print_string_cb);
+ message_register(MSG_DEBUGLEVEL, print_pid_string_cb);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
/* Send a print notify message */
-static BOOL do_printnotify(const pid_t pid, const int argc, char **argv)
+static BOOL do_printnotify(const struct process_id pid,
+ const int argc, const char **argv)
{
- char *cmd;
+ const char *cmd;
/* Check for subcommand */
return False;
}
- notify_printer_byname(argv[2], attribute, argv[4]);
+ notify_printer_byname(argv[2], attribute,
+ CONST_DISCARD(char *, argv[4]));
goto send;
}
/* Close a share */
-static BOOL do_closeshare(const pid_t pid, const int argc, char **argv)
+static BOOL do_closeshare(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> close-share "
/* Force a SAM synchronisation */
-static BOOL do_samsync(const pid_t pid, const int argc, char **argv)
+static BOOL do_samsync(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> samsync\n");
/* Force a SAM replication */
-static BOOL do_samrepl(const pid_t pid, const int argc, char **argv)
+static BOOL do_samrepl(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> samrepl\n");
/* Display talloc pool usage */
-static BOOL do_poolusage(const pid_t pid, const int argc, char **argv)
+static BOOL do_poolusage(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> pool-usage\n");
message_register(MSG_POOL_USAGE, print_string_cb);
- wait_replies(pid == 0);
+ wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
/* Perform a dmalloc mark */
-static BOOL do_dmalloc_mark(const pid_t pid, const int argc, char **argv)
+static BOOL do_dmalloc_mark(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> dmalloc-mark\n");
/* Perform a dmalloc changed */
-static BOOL do_dmalloc_changed(const pid_t pid, const int argc,
- char **argv)
+static BOOL do_dmalloc_changed(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> "
/* Shutdown a server process */
-static BOOL do_shutdown(const pid_t pid, const int argc, char **argv)
+static BOOL do_shutdown(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> shutdown\n");
/* Notify a driver upgrade */
-static BOOL do_drvupgrade(const pid_t pid, const int argc, char **argv)
+static BOOL do_drvupgrade(const struct process_id pid,
+ const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> drvupgrade "
pid, MSG_DEBUG, argv[1], strlen(argv[1]) + 1, False);
}
+static BOOL do_reload_config(const struct process_id pid,
+ const int argc, const char **argv)
+{
+ if (argc != 1) {
+ fprintf(stderr, "Usage: smbcontrol <dest> reload-config\n");
+ return False;
+ }
+
+ return send_message(pid, MSG_SMB_CONF_UPDATED, NULL, 0, False);
+}
+
+static void my_make_nmb_name( struct nmb_name *n, const char *name, int type)
+{
+ fstring unix_name;
+ memset( (char *)n, '\0', sizeof(struct nmb_name) );
+ fstrcpy(unix_name, name);
+ strupper_m(unix_name);
+ push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
+ n->name_type = (unsigned int)type & 0xFF;
+ push_ascii(n->scope, global_scope(), 64, STR_TERMINATE);
+}
+
+static BOOL do_nodestatus(const struct process_id pid,
+ const int argc, const char **argv)
+{
+ struct packet_struct p;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: smbcontrol nmbd nodestatus <ip>\n");
+ return False;
+ }
+
+ ZERO_STRUCT(p);
+
+ p.ip = *interpret_addr2(argv[1]);
+ p.port = 137;
+ p.packet_type = NMB_PACKET;
+
+ p.packet.nmb.header.name_trn_id = 10;
+ p.packet.nmb.header.opcode = 0;
+ p.packet.nmb.header.response = False;
+ p.packet.nmb.header.nm_flags.bcast = False;
+ p.packet.nmb.header.nm_flags.recursion_available = False;
+ p.packet.nmb.header.nm_flags.recursion_desired = False;
+ p.packet.nmb.header.nm_flags.trunc = False;
+ p.packet.nmb.header.nm_flags.authoritative = False;
+ p.packet.nmb.header.rcode = 0;
+ p.packet.nmb.header.qdcount = 1;
+ p.packet.nmb.header.ancount = 0;
+ p.packet.nmb.header.nscount = 0;
+ p.packet.nmb.header.arcount = 0;
+ my_make_nmb_name(&p.packet.nmb.question.question_name, "*", 0x00);
+ p.packet.nmb.question.question_type = 0x21;
+ p.packet.nmb.question.question_class = 0x1;
+
+ return send_message(pid, MSG_SEND_PACKET, &p, sizeof(p), False);
+}
+
/* A list of message type supported */
static const struct {
const char *name; /* Option name */
- BOOL (*fn)(const pid_t pid, const int argc, char **argv);
+ BOOL (*fn)(const struct process_id pid,
+ const int argc, const char **argv);
const char *help; /* Short help text */
} msg_types[] = {
{ "debug", do_debug, "Set debuglevel" },
{ "dmalloc-log-changed", do_dmalloc_changed, "" },
{ "shutdown", do_shutdown, "Shut down daemon" },
{ "drvupgrade", do_drvupgrade, "Notify a printer driver has changed" },
+ { "reload-config", do_reload_config, "Force smbd or winbindd to reload config file"},
+ { "nodestatus", do_nodestatus, "Ask nmbd to do a node status request"},
{ "noop", do_noop, "Do nothing" },
{ NULL }
};
-/* Yuck - we need these because we link to printing*.o even though
- they aren't used. */
-
-void become_root(void) {}
-void unbecome_root(void) {}
-
/* Display usage information */
static void usage(poptContext *pc)
/* Return the pid number for a string destination */
-static pid_t parse_dest(char *dest)
+static struct process_id parse_dest(const char *dest)
{
+ struct process_id result;
pid_t pid;
/* Zero is a special return value for broadcast smbd */
- if (strequal(dest, "smbd"))
- return 0;
+ if (strequal(dest, "smbd")) {
+ return interpret_pid("0");
+ }
/* Try self - useful for testing */
- if (strequal(dest, "self"))
- return sys_getpid();
+ if (strequal(dest, "self")) {
+ return pid_to_procid(sys_getpid());
+ }
/* Check for numeric pid number */
- if ((pid = atoi(dest)) != 0)
- return pid;
+ result = interpret_pid(dest);
+ if (procid_valid(&result)) {
+ return result;
+ }
/* Look up other destinations in pidfile directory */
- if ((pid = pidfile_pid(dest)) != 0)
- return pid;
+ if ((pid = pidfile_pid(dest)) != 0) {
+ return pid_to_procid(pid);
+ }
fprintf(stderr,"Can't find pid for destination '%s'\n", dest);
- return -1;
+ return result;
}
/* Execute smbcontrol command */
-static BOOL do_command(int argc, char **argv)
+static BOOL do_command(int argc, const char **argv)
{
- char *dest = argv[0], *command = argv[1];
- pid_t pid;
+ const char *dest = argv[0], *command = argv[1];
+ struct process_id pid;
int i;
/* Check destination */
- if ((pid = parse_dest(dest)) == -1)
+ pid = parse_dest(dest);
+ if (!procid_valid(&pid)) {
return False;
+ }
/* Check command */
/* Main program */
-int main(int argc, char **argv)
+int main(int argc, const char **argv)
{
poptContext pc;
int opt;
- struct poptOption wbinfo_options[] = {
+ static struct poptOption wbinfo_options[] = {
{ "timeout", 't', POPT_ARG_INT, &timeout, 't',
"Set timeout value in seconds", "TIMEOUT" },
argc -= 2;
break;
case 's': /* --configfile */
- pstrcpy(dyn_CONFIGFILE, optarg);
+ pstrcpy(dyn_CONFIGFILE, poptGetOptArg(pc));
argc -= 2;
break;
default:
argv. The argc parameter should have been decremented to the
correct value in the above switch statement. */
- argv = (char **)poptGetArgs(pc);
+ argv = (const char **)poptGetArgs(pc);
argc--; /* Don't forget about argv[0] */
if (argc == 1)