]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
I needed a decently parseable format of smbstatus. Looking at smbstatus code
authorVolker Lendecke <vlendec@samba.org>
Mon, 1 Dec 2003 14:02:24 +0000 (14:02 +0000)
committerVolker Lendecke <vlendec@samba.org>
Mon, 1 Dec 2003 14:02:24 +0000 (14:02 +0000)
tells me that this should not be expanded, so I implemented

net status [sessions|shares] [parseable]

Volker

source/Makefile.in
source/utils/net.c
source/utils/net_help.c
source/utils/net_status.c [new file with mode: 0644]

index dd8aaee6c409f0da561a398610db5580ac7f8323..d225b88f41891c37b966d5cc4fee49fcc4545b68 100644 (file)
@@ -506,7 +506,8 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
 NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
           utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
           utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
-          utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o
+          utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
+          utils/net_status.o
 
 NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
          $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
index 75fa607caefb83e0433ae062aff1f1099f338d27..4d2b1eb439b99ea7017d3af2ff9b9860f00f5137 100644 (file)
@@ -616,6 +616,7 @@ static struct functable net_func[] = {
        {"GETDOMAINSID", net_getdomainsid},
        {"MAXRID", net_maxrid},
        {"IDMAP", net_idmap},
+       {"STATUS", net_status},
 #ifdef WITH_FAKE_KASERVER
        {"AFSKEY", net_afskey},
 #endif
index 514cf1af1b2036f171cc03ab247266f71d622e30..e444978ea8d7ef42f09448364e4c6302d3e7b040 100644 (file)
@@ -149,6 +149,15 @@ int net_help_file(int argc, const char **argv)
        return -1;
 }
 
+int net_help_status(int argc, const char **argv)
+{
+       d_printf("  net status sessions [parseable]"
+                "\t\t\tShow list of open sessions\n");
+       d_printf("  net status shares [parseable]"
+                "\t\t\tShow list of open shares\n");
+       return -1;
+}
+
 static int net_usage(int argc, const char **argv)
 {
        d_printf("  net time\t\tto view or set time information\n"\
@@ -162,6 +171,7 @@ static int net_usage(int argc, const char **argv)
                 "  net setlocalsid SID\tto set the local domain SID\n"\
                 "  net changesecretpw\tto change the machine password in the local secrets database only\n"\
                 "                    \tthis requires the -f flag as a safety barrier\n"\
+                "  net status\t\tShow server status\n"\
                 "\n"\
                 "  net ads <command>\tto run ADS commands\n"\
                 "  net rap <command>\tto run RAP (pre-RPC) commands\n"\
diff --git a/source/utils/net_status.c b/source/utils/net_status.c
new file mode 100644 (file)
index 0000000..0543f45
--- /dev/null
@@ -0,0 +1,257 @@
+/* 
+   Samba Unix/Linux SMB client library 
+   net status command -- possible replacement for smbstatus
+   Copyright (C) 2003 Volker Lendecke (vl@samba.org)
+
+   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.  */
+
+#include "includes.h"
+#include "../utils/net.h"
+
+static int show_session(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+                       void *state)
+{
+       BOOL *parseable = (BOOL *)state;
+       struct sessionid sessionid;
+
+       if (dbuf.dsize != sizeof(sessionid))
+               return 0;
+
+       memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
+
+       if (!process_exists(sessionid.pid)) {
+               return 0;
+       }
+
+       if (*parseable) {
+               d_printf("%d\\%s\\%s\\%s\\%s\n",
+                        (int)sessionid.pid, uidtoname(sessionid.uid),
+                        gidtoname(sessionid.gid), 
+                        sessionid.remote_machine, sessionid.hostname);
+       } else {
+               d_printf("%5d   %-12s  %-12s  %-12s (%s)\n",
+                        (int)sessionid.pid, uidtoname(sessionid.uid),
+                        gidtoname(sessionid.gid), 
+                        sessionid.remote_machine, sessionid.hostname);
+       }
+
+       return 0;
+}
+
+static int net_status_sessions(int argc, const char **argv)
+{
+       TDB_CONTEXT *tdb;
+       BOOL parseable;
+
+       if (argc == 0) {
+               parseable = False;
+       } else if ((argc == 1) && strequal(argv[0], "parseable")) {
+               parseable = True;
+       } else {
+               return net_help_status(argc, argv);
+       }
+
+       if (!parseable) {
+               d_printf("PID     Username      Group         Machine"
+                        "                        \n");
+               d_printf("-------------------------------------------"
+                        "------------------------\n");
+       }
+
+       tdb = tdb_open_log(lock_path("sessionid.tdb"), 0,
+                          TDB_DEFAULT, O_RDONLY, 0);
+
+       if (tdb == NULL) {
+               d_printf("%s not initialised\n", lock_path("sessionid.tdb"));
+               return -1;
+       }
+
+       tdb_traverse(tdb, show_session, &parseable);
+       tdb_close(tdb);
+
+       return 0;
+}
+
+static int show_share(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+                     void *state)
+{
+       struct connections_data crec;
+
+       if (dbuf.dsize != sizeof(crec))
+               return 0;
+
+       memcpy(&crec, dbuf.dptr, sizeof(crec));
+
+       if (crec.cnum == -1)
+               return 0;
+
+       if (!process_exists(crec.pid)) {
+               return 0;
+       }
+
+       d_printf("%-10.10s   %5d   %-12s  %s",
+              crec.name,(int)crec.pid,
+              crec.machine,
+              asctime(LocalTime(&crec.start)));
+
+       return 0;
+}
+
+struct sessionids {
+       int num_entries;
+       struct sessionid *entries;
+};
+
+static int collect_pid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+                      void *state)
+{
+       struct sessionids *ids = (struct sessionids *)state;
+       struct sessionid sessionid;
+
+       if (dbuf.dsize != sizeof(sessionid))
+               return 0;
+
+       memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
+
+       if (!process_exists(sessionid.pid))
+               return 0;
+
+       ids->num_entries += 1;
+       ids->entries = Realloc(ids->entries,
+                              sizeof(struct sessionid) * ids->num_entries);
+       ids->entries[ids->num_entries-1] = sessionid;
+
+       return 0;
+}
+
+static int show_share_parseable(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+                               void *state)
+{
+       struct sessionids *ids = (struct sessionids *)state;
+       struct connections_data crec;
+       int i;
+       BOOL guest = True;
+
+       if (dbuf.dsize != sizeof(crec))
+               return 0;
+
+       memcpy(&crec, dbuf.dptr, sizeof(crec));
+
+       if (crec.cnum == -1)
+               return 0;
+
+       if (!process_exists(crec.pid)) {
+               return 0;
+       }
+
+       for (i=0; i<ids->num_entries; i++) {
+               if (ids->entries[i].pid == crec.pid) {
+                       guest = False;
+                       break;
+               }
+       }
+
+       d_printf("%s\\%d\\%s\\%s\\%s\\%s\\%s",
+                crec.name,(int)crec.pid,
+                guest ? "" : uidtoname(ids->entries[i].uid),
+                guest ? "" : gidtoname(ids->entries[i].gid),
+                crec.machine, 
+                guest ? "" : ids->entries[i].hostname,
+                asctime(LocalTime(&crec.start)));
+
+       return 0;
+}
+
+static int net_status_shares_parseable(int argc, const char **argv)
+{
+       struct sessionids ids;
+       TDB_CONTEXT *tdb;
+
+       ids.num_entries = 0;
+       ids.entries = NULL;
+
+       tdb = tdb_open_log(lock_path("sessionid.tdb"), 0,
+                          TDB_DEFAULT, O_RDONLY, 0);
+
+       if (tdb == NULL) {
+               d_printf("%s not initialised\n", lock_path("sessionid.tdb"));
+               return -1;
+       }
+
+       tdb_traverse(tdb, collect_pid, &ids);
+       tdb_close(tdb);
+
+       tdb = tdb_open_log(lock_path("connections.tdb"), 0,
+                          TDB_DEFAULT, O_RDONLY, 0);
+
+       if (tdb == NULL) {
+               d_printf("%s not initialised\n", lock_path("connections.tdb"));
+               d_printf("This is normal if no SMB client has ever connected "
+                        "to your server.\n");
+               return -1;
+       }
+
+       tdb_traverse(tdb, show_share_parseable, &ids);
+       tdb_close(tdb);
+
+       SAFE_FREE(ids.entries);
+
+       return 0;
+}
+
+static int net_status_shares(int argc, const char **argv)
+{
+       TDB_CONTEXT *tdb;
+
+       if (argc == 0) {
+
+               d_printf("\nService      pid     machine       "
+                        "Connected at\n");
+               d_printf("-------------------------------------"
+                        "------------------\n");
+
+               tdb = tdb_open_log(lock_path("connections.tdb"), 0,
+                                  TDB_DEFAULT, O_RDONLY, 0);
+
+               if (tdb == NULL) {
+                       d_printf("%s not initialised\n",
+                                lock_path("connections.tdb"));
+                       d_printf("This is normal if no SMB client has ever "
+                                "connected to your server.\n");
+                       return -1;
+               }
+
+               tdb_traverse(tdb, show_share, NULL);
+               tdb_close(tdb);
+
+               return 0;
+       }
+
+       if ((argc != 1) || !strequal(argv[0], "parseable")) {
+               return net_help_status(argc, argv);
+       }
+
+       return net_status_shares_parseable(argc, argv);
+}
+
+int net_status(int argc, const char **argv)
+{
+       struct functable func[] = {
+               {"sessions", net_status_sessions},
+               {"shares", net_status_shares},
+               {NULL, NULL}
+       };
+       return net_run_function(argc, argv, func, net_help_status);
+}