2012/2/1 Arnaud Quette <[email protected]>

> 2012/1/25 Rene Martín Rodríguez <[email protected]>:
> > Hello!!
>
> ¡Hola René Martin ;-)
>
> Hi again!

I've implemented your suggestion, everything but -c option for upsc. hope
you like it!



> indeed, it's an interesting feature.
>
> after thinking a bit, here is a potentially more useful approach, that
> would complement "GET NUMLOGINS":
> Add a new "LIST CLIENT" command to the network protocol [1]
>
> Form:
>
>    LIST CLIENT [device_name]
>
> Response:
>
>    BEGIN LIST CLIENT
>    CLIENT <client IP address> <device name>
>    ...
>    END LIST CLIENT
>
>    BEGIN LIST CLIENT
>    CLIENT ::1 ups1
>    CLIENT ::1 ups2
>    CLIENT 166.99.250.2 ups2
>    END LIST CLIENT
>
> This would be completed by a new upsc option ("-c" for example) to get
> this list.
>
> Note that this is more an RFC, since it's just a base idea (I've not
> checked all details).
> So feedback and comments welcome...
> Would the above suits your needs René Martin?
>
> > Thank you for your nice work!!
>
> thanks for your contribution.
>
> cheers,
> Arnaud
> --
> [1]
> http://www.networkupstools.org/docs/developer-guide.chunked/ar01s09.html
> --
> Linux / Unix Expert R&D - Eaton - http://powerquality.eaton.com
> Network UPS Tools (NUT) Project Leader - http://www.networkupstools.org/
> Debian Developer - http://www.debian.org
> Free Software Developer - http://arnaud.quette.free.fr/
>
Index: server/upsd.c
===================================================================
--- server/upsd.c	(revisión: 3431)
+++ server/upsd.c	(copia de trabajo)
@@ -65,7 +65,7 @@
 	/* everything else */
 	const char	*progname;
 
-static nut_ctype_t	*firstclient = NULL;
+    nut_ctype_t	*firstclient = NULL;
 /* static nut_ctype_t	*lastclient = NULL; */
 
 	/* default is to listen on all local interfaces */
@@ -92,7 +92,7 @@
 static char	pidfn[SMALLBUF];
 
 	/* set by signal handlers */
-static int	reload_flag = 0, exit_flag = 0;
+static int	reload_flag = 0, exit_flag = 0, info_flag = 0;
 
 static const char *inet_ntopW (struct sockaddr_storage *s)
 {
@@ -664,6 +664,21 @@
 	handler = xrealloc(handler, maxconn * sizeof(*handler));
 }
 
+/* log client info */
+static void client_info(void)
+{
+	nut_ctype_t		*client, *cnext;
+
+    if (firstclient) {
+        /* show connected clients */
+        for (client = firstclient; client; client = cnext) {
+            cnext = client->next;
+            upslogx(LOG_INFO, "Client %s connected to UPS [%s]\n", client->addr, client->loginups);
+        }
+    } else
+        upslogx(LOG_INFO, "There isn't any connected client\n");
+}
+
 /* service requests and check on new data */
 static void mainloop(void)
 {
@@ -682,6 +697,11 @@
 		reload_flag = 0;
 	}
 
+	if (info_flag) {
+        client_info();
+        info_flag = 0;
+	}
+
 	/* scan through driver sockets */
 	for (ups = firstups; ups && (nfds < maxconn); ups = ups->next) {
 
@@ -818,6 +838,7 @@
 	printf("		commands:\n");
 	printf("		 - reload: reread configuration files\n");
 	printf("		 - stop: stop process and exit\n");
+	printf("		 - info: print client information via syslog and exit\n");
 	printf("  -D		raise debugging level\n");
 	printf("  -h		display this help\n");
 	printf("  -r <dir>	chroots to <dir>\n");
@@ -840,6 +861,11 @@
 	exit_flag = sig;
 }
 
+static void set_info_flag(int sig)
+{
+	info_flag = 1;
+}
+
 static void setup_signals(void)
 {
 	struct sigaction	sa;
@@ -861,6 +887,10 @@
 	/* handle reloading */
 	sa.sa_handler = set_reload_flag;
 	sigaction(SIGHUP, &sa, NULL);
+
+	/* Show connectd clients */
+	sa.sa_handler = set_info_flag;
+	sigaction(SIGCMD_INFO, &sa, NULL);
 }
 
 void check_perms(const char *fn)
@@ -926,6 +956,8 @@
 					cmd = SIGCMD_RELOAD;
 				if (!strncmp(optarg, "stop", strlen(optarg)))
 					cmd = SIGCMD_STOP;
+				if (!strncmp(optarg, "info", strlen(optarg)))
+					cmd = SIGCMD_INFO;
 
 				/* bad command given */
 				if (cmd == 0)
Index: server/upsd.h
===================================================================
--- server/upsd.h	(revisión: 3431)
+++ server/upsd.h	(copia de trabajo)
@@ -67,11 +67,13 @@
 extern int		maxage, maxconn;
 extern char		*statepath, *datapath;
 extern upstype_t	*firstups;
+extern nut_ctype_t	*firstclient;
 
 /* map commands onto signals */
 
 #define SIGCMD_STOP	SIGTERM
 #define SIGCMD_RELOAD	SIGHUP
+#define SIGCMD_INFO	SIGUSR1
 
 /* awkward way to make a string out of a numeric constant */
 
Index: server/netlist.c
===================================================================
--- server/netlist.c	(revisión: 3431)
+++ server/netlist.c	(copia de trabajo)
@@ -26,7 +26,8 @@
 
 #include "netlist.h"
 
-	extern	upstype_t	*firstups;	/* for list_ups */
+extern	upstype_t	*firstups;	/* for list_ups */
+extern	nut_ctype_t *firstclient;	/* for list_clients */
 
 static int tree_dump(st_tree_t *node, nut_ctype_t *client, const char *ups,
 	int rw, int fsd)
@@ -217,6 +218,40 @@
 	sendback(client, "END LIST UPS\n");
 }	
 
+static void list_clients(nut_ctype_t *client, const char *upsname)
+{
+	const   upstype_t *ups;
+	nut_ctype_t		*c, *cnext;
+    ups = NULL;
+
+    if (strcasecmp(upsname, "")) {
+	    ups = get_ups_ptr(upsname);
+        if (!ups) {
+            send_err(client, NUT_ERR_UNKNOWN_UPS);
+            return;
+        }
+    }
+
+	if (!sendback(client, "BEGIN LIST CLIENTS\n"))
+		return;
+
+    if (firstclient) {
+		int	ret;
+        /* show connected clients */
+        for (c = firstclient; c; c = cnext) {
+            if (c->loginups && (!ups || !strcasecmp(c->loginups, ups->name))) {
+                ret = sendback(client, "CLIENT %s %s\n", c->addr, c->loginups);
+                if (!ret)
+                    return;
+            }
+            cnext = c->next;
+        }
+    }
+	sendback(client, "END LIST CLIENTS\n");
+
+
+}	
+
 void net_list(nut_ctype_t *client, int numarg, const char **arg)
 {
 	if (numarg < 1) {
@@ -230,6 +265,12 @@
 		return;
 	}
 
+	/* LIST CLIENTS */
+	if (!strcasecmp(arg[0], "CLIENTS") && (numarg == 1)) {
+		list_clients(client, "");
+		return;
+	}
+
 	if (numarg < 2) {
 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
 		return;
@@ -253,6 +294,12 @@
 		return;
 	}
 
+	/* LIST CLIENTS */
+	if (!strcasecmp(arg[0], "CLIENTS")) {
+		list_clients(client, arg[1]);
+		return;
+	}
+
 	if (numarg < 3) {
 		send_err(client, NUT_ERR_INVALID_ARGUMENT);
 		return;
Index: PyNUT.py
===================================================================
--- PyNUT.py	(revisión: 2649)
+++ PyNUT.py	(copia de trabajo)
@@ -294,3 +294,35 @@
 
         self.__srv_handler.write( "VER\n")
         return self.__srv_handler.read_until( "\n" )
+
+    def ListClients( self, ups = None ) :
+        """ Returns the list of connected clients from the NUT server
+
+The result is a dictionnary containing 'key->val' pairs of 'UPSName' and a list of clients
+        """
+        if self.__debug :
+            print( "[DEBUG] ListClients from server" )
+
+        if ups and (ups not in self.GetUPSList()):
+            raise Exception, "%s is not a valid UPS" % ups
+
+        if ups:
+            self.__srv_handler.write( "LIST CLIENTS %s\n" % ups)
+        else:
+            self.__srv_handler.write( "LIST CLIENTS\n" )
+        result = self.__srv_handler.read_until( "\n" )
+        if result != "BEGIN LIST CLIENTS\n" :
+            raise Exception, result.replace( "\n", "" )
+
+        result = self.__srv_handler.read_until( "END LIST CLIENTS\n" )
+        ups_list = {}
+
+        for line in result.split( "\n" ):
+            if line[:6] == "CLIENT" :
+                host, ups = line[7:].split(' ')
+                ups.replace(' ', '')
+                if not ups in ups_list:
+                    ups_list[ups] = []
+                ups_list[ups].append(host)
+
+        return( ups_list )
_______________________________________________
Nut-upsdev mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/nut-upsdev

Reply via email to