r21064: The core of this patch is
[samba.git] / source3 / utils / smbcontrol.c
index c368ee0ad4cb0428bb794c83fe2036c06fde48d9..26e2b82ae68d2b28e13270337ad1dd2b50478a9d 100644 (file)
@@ -98,7 +98,8 @@ static void wait_replies(BOOL multiple_replies)
 
 /* 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)
+static void print_pid_string_cb(int msg_type, struct process_id pid, void *buf,
+                               size_t len, void *private_data)
 {
        printf("PID %u: %.*s", (unsigned int)procid_to_pid(&pid),
               (int)len, (const char *)buf);
@@ -108,7 +109,7 @@ static void print_pid_string_cb(int msg_type, struct process_id pid, void *buf,
 /* Message handler callback that displays a string on stdout */
 
 static void print_string_cb(int msg_type, struct process_id pid,
-                           void *buf, size_t len)
+                           void *buf, size_t len, void *private_data)
 {
        printf("%.*s", (int)len, (const char *)buf);
        num_replies++;
@@ -371,7 +372,8 @@ static BOOL do_election(const struct process_id pid,
 
 /* Ping a samba daemon process */
 
-static void pong_cb(int msg_type, struct process_id pid, void *buf, size_t len)
+static void pong_cb(int msg_type, struct process_id pid, void *buf,
+                   size_t len, void *private_data)
 {
        char *src_string = procid_str(NULL, &pid);
        printf("PONG from pid %s\n", src_string);
@@ -391,7 +393,7 @@ static BOOL do_ping(const struct process_id pid, const int argc, const char **ar
        if (!send_message(pid, MSG_PING, NULL, 0, False))
                return False;
 
-       message_register(MSG_PONG, pong_cb);
+       message_register(MSG_PONG, pong_cb, NULL);
 
        wait_replies(procid_to_pid(&pid) == 0);
 
@@ -436,7 +438,8 @@ static BOOL do_profile(const struct process_id pid,
 
 /* Return the profiling level */
 
-static void profilelevel_cb(int msg_type, struct process_id pid, void *buf, size_t len)
+static void profilelevel_cb(int msg_type, struct process_id pid, void *buf,
+                           size_t len, void *private_data)
 {
        int level;
        const char *s;
@@ -473,7 +476,7 @@ static void profilelevel_cb(int msg_type, struct process_id pid, void *buf, size
 }
 
 static void profilelevel_rqst(int msg_type, struct process_id pid,
-                             void *buf, size_t len)
+                             void *buf, size_t len, void *private_data)
 {
        int v = 0;
 
@@ -495,8 +498,8 @@ static BOOL do_profilelevel(const struct process_id pid,
        if (!send_message(pid, MSG_REQ_PROFILELEVEL, NULL, 0, False))
                return False;
 
-       message_register(MSG_PROFILELEVEL, profilelevel_cb);
-       message_register(MSG_REQ_PROFILELEVEL, profilelevel_rqst);
+       message_register(MSG_PROFILELEVEL, profilelevel_cb, NULL);
+       message_register(MSG_REQ_PROFILELEVEL, profilelevel_rqst, NULL);
 
        wait_replies(procid_to_pid(&pid) == 0);
 
@@ -525,7 +528,7 @@ static BOOL do_debuglevel(const struct process_id pid,
        if (!send_message(pid, MSG_REQ_DEBUGLEVEL, NULL, 0, False))
                return False;
 
-       message_register(MSG_DEBUGLEVEL, print_pid_string_cb);
+       message_register(MSG_DEBUGLEVEL, print_pid_string_cb, NULL);
 
        wait_replies(procid_to_pid(&pid) == 0);
 
@@ -732,7 +735,7 @@ static BOOL do_poolusage(const struct process_id pid,
                return False;
        }
 
-       message_register(MSG_POOL_USAGE, print_string_cb);
+       message_register(MSG_POOL_USAGE, print_string_cb, NULL);
 
        /* Send a message and register our interest in a reply */
 
@@ -882,25 +885,27 @@ static BOOL do_winbind_offline(const struct process_id pid,
           5 times. */
 
        for (retry = 0; retry < 5; retry++) {
-               int err;
                TDB_DATA d;
+               char buf[4];
+
                ZERO_STRUCT(d);
+
+               SIVAL(buf, 0, time(NULL));
+               d.dptr = buf;
+               d.dsize = 4;
+
                tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT);
 
                ret = send_message(pid, MSG_WINBIND_OFFLINE, NULL, 0, False);
 
                /* Check that the entry "WINBINDD_OFFLINE" still exists. */
-               tdb->ecode = 0;
                d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" );
-
-               /* As this is a key with no data we don't need to free, we
-                  check for existence by looking at tdb_err. */
-
-               err = tdb_error(tdb);
-
-               if (err == TDB_ERR_NOEXIST) {
+       
+               if (!d.dptr || d.dsize != 4) {
+                       SAFE_FREE(d.dptr);
                        DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n"));
                } else {
+                       SAFE_FREE(d.dptr);
                        break;
                }
        }
@@ -909,6 +914,36 @@ static BOOL do_winbind_offline(const struct process_id pid,
        return ret;
 }
 
+static BOOL do_winbind_onlinestatus(const struct process_id pid,
+                                   const int argc, const char **argv)
+{
+       struct process_id myid;
+
+       myid = pid_to_procid(sys_getpid());
+
+       if (argc != 1) {
+               fprintf(stderr, "Usage: smbcontrol winbindd onlinestatus\n");
+               return False;
+       }
+
+       message_register(MSG_WINBIND_ONLINESTATUS, print_pid_string_cb, NULL);
+
+       if (!send_message(pid, MSG_WINBIND_ONLINESTATUS, &myid, sizeof(myid), False))
+               return False;
+
+       wait_replies(procid_to_pid(&pid) == 0);
+
+       /* No replies were received within the timeout period */
+
+       if (num_replies == 0)
+               printf("No replies received\n");
+
+       message_deregister(MSG_WINBIND_ONLINESTATUS);
+
+       return num_replies;
+}
+
+
 static BOOL do_reload_config(const struct process_id pid,
                             const int argc, const char **argv)
 {
@@ -999,6 +1034,7 @@ static const struct {
        { "nodestatus", do_nodestatus, "Ask nmbd to do a node status request"},
        { "online", do_winbind_online, "Ask winbind to go into online state"},
        { "offline", do_winbind_offline, "Ask winbind to go into offline state"},
+       { "onlinestatus", do_winbind_onlinestatus, "Request winbind online status"},
        { "noop", do_noop, "Do nothing" },
        { NULL }
 };