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