[Nut-upsdev] [PATCH 09/36] first cut at fixing the insanity of using perl and python scripts to parse C sources and generate new header files
Greg A. Woods
woods at planix.com
Thu Mar 8 23:21:20 UTC 2012
From: "Greg A. Woods" <woods at planix.com>
nut-scanner currently compiles using two header files which are built
from information in some of the C sources of various drivers. This is
kinda bogus, but worst of all was how these headers were generated.
I've entirely deprecated the Python script that parsed drivers/*-mib.c
files to generate tools/nut-scanner/nutscan-snmp.h. That header is now
generated by a magic new option to the snmp-ups driver itself. This is
a temporary solution as it is not friendly to cross-compilation.
Ultimately the *-mib.c files, and the table they are linked together
with, should be moved to common code which both the driver and
nut-scanner can link directly with.
The generation of tools/nut-scanner/nutscan-usb.h has been moved into
the tools/nut-scanner/Makefile.am for now and made to run only when one
of the drivers/*_usb.c files changes (which depends on use of GNU Make),
though it too should be entirely eliminated as above.
---
drivers/snmp-ups.c | 47 +++++++++++++++++++++++++++++++++
drivers/snmp-ups.h | 1 +
tools/Makefile.am | 58 +++--------------------------------------
tools/nut-scanner/.gitignore | 5 ++--
tools/nut-scanner/Makefile.am | 38 ++++++++++++++++++++++++---
tools/nut-usbinfo.pl | 12 ++++-----
6 files changed, 95 insertions(+), 66 deletions(-)
diff --git a/drivers/snmp-ups.c b/drivers/snmp-ups.c
index 3722d34..12eff77 100644
--- a/drivers/snmp-ups.c
+++ b/drivers/snmp-ups.c
@@ -89,6 +89,7 @@ const char *mibname;
const char *mibvers;
static void disable_transfer_oids(void);
+static void dump_nutscanner_snmp(void);
#define DRIVER_NAME "Generic SNMP UPS driver"
#define DRIVER_VERSION "0.66"
@@ -248,6 +249,7 @@ void upsdrv_makevartable(void)
"Set the authentication protocol (MD5 or SHA) used for authenticated SNMPv3 messages (default=MD5)");
addvar(VAR_VALUE, SU_VAR_PRIVPROT,
"Set the privacy protocol (DES or AES) used for encrypted SNMPv3 messages (default=DES)");
+ addvar(VAR_FLAG, SU_VAR_MAGIC, "Run the secret magic header dumper");
}
void upsdrv_initups(void)
@@ -259,6 +261,11 @@ void upsdrv_initups(void)
upsdebugx(1, "SNMP UPS driver : entering upsdrv_initups()");
+ if (testvar(SU_VAR_MAGIC)) {
+ dump_nutscanner_snmp();
+ exit(0);
+ }
+
/* Retrieve user's parameters */
mibs = testvar(SU_VAR_MIBS) ? getval(SU_VAR_MIBS) : "auto";
@@ -1667,8 +1674,48 @@ void su_shutdown_ups(void)
}
}
+static void dump_nutscanner_snmp()
+{
+ int i;
+
+ printf("/*\n");
+ printf(" * nutscan-snmp.h\n");
+ printf(" *\n");
+ printf(" * WARNING!!! This file was automatically generated by snmp-ups!\n");
+ printf(" */\n");
+ printf("\n");
+ printf("#ifndef DEVSCAN_SNMP_H\n");
+ printf("#define DEVSCAN_SNMP_H\n");
+ printf("\n");
+ printf("typedef struct {\n");
+ printf("\tchar *oid;\n");
+ printf("\tchar *mib;\n");
+ printf("\tchar *sysoid;\n");
+ printf("} snmp_device_id_t;\n");
+ printf("\n");
+ printf("/* SNMP IDs device table */\n");
+ printf("static snmp_device_id_t snmp_device_table[] = {\n");
+
+ /* Now, iterate on mib2nut definitions */
+ for (i = 0; mib2nut[i] != NULL; i++) {
+ printf("\t{ \"%s\", \"%s\", %s%s%s},\n",
+ mib2nut[i]->oid_auto_check,
+ mib2nut[i]->mib_name,
+ mib2nut[i]->sysOID ? "\"" : "",
+ mib2nut[i]->sysOID ? mib2nut[i]->sysOID : "NULL",
+ mib2nut[i]->sysOID ? "\"" : "");
+ }
+
+ printf("\t/* Terminating entry */\n");
+ printf("\t{ NULL, NULL, NULL}\n");
+ printf("};\n" );
+ printf("#endif /* DEVSCAN_SNMP_H */\n");
+}
+
+
/* FIXME: the below functions can be removed since these were for loading
* the mib2nut information from a file instead of the .h definitions... */
+/* XXX maybe that's not a good idea -- it would be nice to have data-driven MIB info again! */
/* return 1 if usable, 0 if not */
static int parse_mibconf_args(int numargs, char **arg)
{
diff --git a/drivers/snmp-ups.h b/drivers/snmp-ups.h
index 60fcc5d..802da9e 100644
--- a/drivers/snmp-ups.h
+++ b/drivers/snmp-ups.h
@@ -179,6 +179,7 @@ typedef struct {
#define SU_VAR_PRIVPASSWD "privPassword"
#define SU_VAR_AUTHPROT "authProtocol"
#define SU_VAR_PRIVPROT "privProtocol"
+#define SU_VAR_MAGIC "magic"
#define SU_INFOSIZE 128
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 88ee285..4f6ae38 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,51 +1,13 @@
# TODO: remove redundancies!
-# XXX this does not work with Automake!!!
-#
-# In fact the very concept is entirely antithetical to Automake.
-#
-# SUBDIRS are explicitly a listing of all the directories that make
-# must recurse into BEFORE processing the current directory.
-#
-# These python scripts must be moved into a sub-directory, and _only_
-# executed IFF they need to be, and all the nut-scanner sources need
-# to be moved out of a sub-directory into this directory.
-#
-# Force build in ./ before nut-scanner, to have nutscan-{usb,snmp}.h
-# built before going into the nut-scanner sub-directory
-#
-#SUBDIRS = . nut-scanner
SUBDIRS = nut-scanner
EXTRA_DIST = nut-usbinfo.pl nut-hclinfo.py device-recorder.sh svn2cl.authors nut-snmpinfo.py
-all: nut-scanner-deps
-
-# XXX these rules are all bogus! They cause un-named target files to
-# always be rebuilt! None of that is ever the right way to use make,
-# and especially not Automake. Explicit filenames and their exact
-# dependencies need to be properly listed.
-
-nut-scanner-deps:
- @if python -c 1; then \
- echo "Regenerating the SNMP helper files."; \
- $(top_srcdir)/tools/nut-snmpinfo.py; \
- else \
- echo "----------------------------------------------------------------------"; \
- echo "Warning: Python is not available."; \
- echo "Skipping the SNMP helper files regeneration."; \
- echo "----------------------------------------------------------------------"; \
- fi
-
- @if perl -e 1; then \
- echo "Regenerating the USB helper files."; \
- $(top_srcdir)/tools/nut-usbinfo.pl; \
- else \
- echo "----------------------------------------------------------------------"; \
- echo "Warning: Perl is not available."; \
- echo "Skipping the USB helper files regeneration."; \
- echo "----------------------------------------------------------------------"; \
- fi
+# XXX this rules is bogus! It causes un-named target files to always
+# be rebuilt! That is never the right way to use make, and especially
+# not Automake. Explicit filenames and their exact dependencies need
+# to be properly listed.
website:
@if python -c "import json,simplejson,lxml"; then \
@@ -60,20 +22,8 @@ website:
fi
# call the USB info script upon "make dist", and if Perl is present
-# call the SNMP info script upon "make dist", and if Python is present
-# and call both for building nut-scanner
# also generate HCL data files
dist-hook:
- @if python -c 1; then \
- echo "Regenerating the SNMP helper files."; \
- $(distdir)/nut-snmpinfo.py; \
- else \
- echo "----------------------------------------------------------------------"; \
- echo "Warning: Python is not available."; \
- echo "Skipping the SNMP helper files regeneration."; \
- echo "----------------------------------------------------------------------"; \
- fi
-
@if perl -e 1; then \
echo "Regenerating the USB helper files."; \
$(distdir)/nut-usbinfo.pl; \
diff --git a/tools/nut-scanner/.gitignore b/tools/nut-scanner/.gitignore
index a7d477c..c849817 100644
--- a/tools/nut-scanner/.gitignore
+++ b/tools/nut-scanner/.gitignore
@@ -1,11 +1,12 @@
-/*.o
/*.la
/*.lo
+/*.o
/.deps
+/.libs
/Makefile
/Makefile.in
/nut-scanner
/nutscan-snmp.h
/nutscan-usb.h
/test-nutscan
-/.libs
+/ups.conf
diff --git a/tools/nut-scanner/Makefile.am b/tools/nut-scanner/Makefile.am
index d4066d2..a734fdc 100644
--- a/tools/nut-scanner/Makefile.am
+++ b/tools/nut-scanner/Makefile.am
@@ -1,7 +1,38 @@
BUILT_SOURCES = nutscan-usb.h nutscan-snmp.h
-nutscan-usb.h nutscan-snmp.h:
- cd ..; $(MAKE) $(AM_MAKEFLAGS) nut-scanner-deps
+# This may be problematical -- hosts without perl but with USB do exist
+#
+# There must be a better way -- perhaps similar to how nutscan-snmp.h
+# is now created...
+#
+nutscan-usb.h: $(top_srcdir)/drivers/*_usb.c
+ @if perl -e 1; then \
+ echo "Regenerating the USB helper files."; \
+ $(top_srcdir)/tools/nut-usbinfo.pl; \
+ else \
+ echo "----------------------------------------------------------------------"; \
+ echo "Warning: Perl is not available."; \
+ echo "Skipping the USB helper files generation."; \
+ echo "Assuming WITH_USB is not going to be defined at build time."; \
+ echo "----------------------------------------------------------------------"; \
+ fi
+
+# XXX note this will not work for cross-compiles!
+#
+# (see the old ../nut-snmpinfo.py as a hint to how this header could
+# be cross-built -- consider rewriting this toool to link directly
+# with the ../drivers/*-mib.o files, and some new module that would
+# contain the mib2nut table, so that this header is not needed)
+#
+nutscan-snmp.h: ups.conf
+ @NUT_CONFPATH=. ../../drivers/snmp-ups -a nut-scanner -x magic | sed 1d > $(@).tmp
+ @cmp -s $(@).tmp $(@) > /dev/null 2>&1 || mv $(@).tmp $(@)
+ @rm -f $(@).tmp
+
+ups.conf:
+ @echo "[nut-scanner]" > $@
+ @echo " driver = snmp-ups" >> $@
+ @echo " port = 127.0.0.1" >> $@
# Only build nut-scanner, and its library, if libltdl was found (required!)
if WITH_LIBLTDL
@@ -47,5 +78,4 @@ else
dist_noinst_HEADERS += nut-scan.h nutscan-device.h nutscan-ip.h nutscan-init.h
endif
-CLEANFILES = nutscan-usb.h nutscan-snmp.h
-
+CLEANFILES = nutscan-usb.h nutscan-snmp.h ups.conf
diff --git a/tools/nut-usbinfo.pl b/tools/nut-usbinfo.pl
index 7833086..bd74bf8 100755
--- a/tools/nut-usbinfo.pl
+++ b/tools/nut-usbinfo.pl
@@ -25,26 +25,26 @@ use File::Find;
use strict;
# path to scan for USB_DEVICE pattern
-my $scanPath="../drivers";
+my $scanPath="../../drivers";
# HAL output file
-my $outputHAL="../scripts/hal/ups-nut-device.fdi.in";
+my $outputHAL="../../scripts/hal/ups-nut-device.fdi.in";
# Hotplug output file
-my $outputHotplug="../scripts/hotplug/libhid.usermap";
+my $outputHotplug="../../scripts/hotplug/libhid.usermap";
# udev output file
-my $outputUdev="../scripts/udev/nut-usbups.rules.in";
+my $outputUdev="../../scripts/udev/nut-usbups.rules.in";
# UPower output file
-my $outputUPower="../scripts/upower/95-upower-hid.rules";
+my $outputUPower="../../scripts/upower/95-upower-hid.rules";
# tmp output, to allow generating the ENV{UPOWER_VENDOR} header list
my $tmpOutputUPower;
# mfr header flag
my $upowerMfrHeaderDone = 0;
# NUT device scanner - C header
-my $outputDevScanner = "./nut-scanner/nutscan-usb.h";
+my $outputDevScanner = "./nutscan-usb.h";
my $GPL_header = "\
* Copyright (C) 2011 - Arnaud Quette <arnaud.quette\@free.fr>\
--
1.7.9.2
More information about the Nut-upsdev
mailing list