~ubuntu-branches/ubuntu/saucy/nut/saucy

« back to all changes in this revision

Viewing changes to clients/upsrw.c

  • Committer: Chuck Short
  • Date: 2013-05-13 12:57:25 UTC
  • Revision ID: zulcss@ubuntu.com-20130513125725-llq8wsohyhq9idsy
* Merge from Debian.  Remaining changes:
  - debian/control:
    + remove Build-Depends on libpowerman0-dev
    + remove nut-powerman-pdu
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut
    groups unconditonally to handle the upgrade from hardy release.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install,
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled
* Non-maintainer upload with fixes for wheezy.
* debian/nut-client.preinst: also revert /etc/nut/nut.conf mangling done
  by postinst during upgrade from lenny to squeeze (Really closes: #677054)
  Thanks to Andreas Beckmann for the review.
* Merge from Debian.  Remaining changes:
  - debian/control:
    + remove Build-Depends on libpowerman0-dev
    + remove nut-powerman-pdu
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut
    groups unconditonally to handle the upgrade from hardy release.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install,
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled
* Dropped the following patches, no longer required:
  - debian/patches/CVE-2012-2944.patch (included upstream)
* Non-maintainer upload with fixes for wheezy.
* Only remove /etc/init.d/nut from previous versions of nut in nut-server
  postinst if there are no local changes.
* Also remove /etc/init.d/nut in nut-client postinst. Thanks to 
  Laurent Bigonville for the hint.
* Only fix permissions of configfiles on first install.
* debian/control: Fix typo in package description. Thanks to Julien Cristau
  for spotting this.
* Non-maintainer upload.
* debian/nut-client.preinst: revert /etc/nut/nut.conf mangling done by older
  versions of the postinst (Closes: #677054)
* debian/rules: Stop the nut-client before nut-server on systems using
  static
  boot ordering (Closes: #679451)
* debian/nut-server.postinst: Remove /etc/init.d/nut on upgrade
  (Closes: #677822)
* Rename nut-server.lintian-overrides to nut-client.lintian-overrides and
  adjust overrides now that ups-monitor is shipped in nut-client package
  (Closes: #677947)
* Add debian/patches/0001-fix-upsmon-regression.patch: Fix upsmon/upssched
  regression (Taken from upstream) (Closes: #679513)
* Move nut metapackage to Section: metapackages
* Also create nut user when installing nut-client package and do not delete
  it on purge anymore (Closes: #682000)
* Drop /etc/default/nut → /etc/nut/nut.conf migration code, migration
  happends before squeeze release and this was against policy to have a
  maintainer script modifying a conffile in the first place (Closes: #684392)
* Add dependency against adduser and lsb-base on nut-client package
* Be sure that client is stopped before the server also when using
  dependencies based boot
* Fix package descriptions (Closes: #678068)
* Also install /bin/upssched-cmd in nut-client package as this script is
  referenced in default upssched.conf config file
* debian/watch: Update watch file
* Be sure that all maintainer scripts are returning 0 at their end
* New upstream release (Closes: #671444)
* acknowledges NMU (Closes: #613643)
* debian/nut-client.init: fix action "start" and use of log_*_*msg
  LSB log functions (Closes: #675619)
* debian/nut-server.preinst: remove obsolete file(s) left in
  /etc/udev/rules.d and related processing: udev files are now located
  in /lib/udev/rules, and there is no reason to modify the dedicated
  USB UPS rules (52-nut-usbups.rules) (Closes: #660072)
* debian/nut-server.init: rewrite to match upsd / drivers startup scope
* debian/nut-client.init: created to match upsmon startup scope
  (Closes: #634858)
* debian/nut.TODO.Debian, debian/Makefile.am: updated to reflect the above
* debian/rules: install nut-client.init, and update to reflect the above
* debian/control, debian/Makefile.am: updated to reflect the above
* debian/control:
  - add Breaks on nut-server (<< 2.6.3-1~)
  - bump Standards-Version to 3.9.3
* debian/nut-client.links: renamed from debian/nut-server.links, since
  ups-monitor is now provided by nut-client initscript
* debian/nut.README.Debian: renamed from nut-server.README.Debian,
  to provide it with both client and server packages
* debian/nut-server.install: add missing drivers (clone-outlet,
  liebert-esp2 and microdowell)
* debian/nut-server.manpages: add missing manual pages (apcsmart-old,
  ivtscd, liebert-esp2 and microdowell)
* SECURITY UPDATE: remote denial of service
 - debian/CVE-2012-2944.patch: limit the set of parsed characters to ' '
   through '~'
 - CVE-2012-2944
* Merge from Debian testing.  Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* New upstream release (Closes: #635186, #598741, #633756, #638221)
* debian/nut-server.{install,manpages}: add richcomm_usb
* debian/nut-server.install, debian/rules: install Avahi service file
* debian/rules, nut-client.install: install Augeas lenses
* debian/nut-server.README.Debian: clarify udev explanation (Closes: #529664)
* debian/patches/0001-fix_spelling_and_typo.patch,
  debian/patches/0003-libupsclient-version.patch: removed since these are now
  fixed upstream
* debian/patches/series: updated
* Merge from debian unstable.  Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* New upstream release (Closes: #594989)
* debian/control:
  - remove legacy Build-Depends for nut-hal-drivers on libdbus and libglib
  - Build-Depends-Indep on docbook-xsl for offline document
    generation (Closes: #635347)
* debian/nut-server.install: add apcsmart-old
* debian/nut-server.init:
  - add udev as Required-Start/Stop (Closes: #642412)
  - remove legacy support for /etc/default/nut (Closes: #638021)
* debian/patches/0003-libupsclient-version.patch: added to fix the missing
  libupsclient version info bump
* debian/libupsclient1-dev.links: update link name
* debian/libupsclient1.symbols: add with upscli_tryconnect
* debian/nut.TODO.Debian: update and complete the TODO list
* Fix FTBFS for Ubuntu (LP: #815760):
  - debian/control: Build-Depends-Indep on docbook-xsl for offline 
    document generation.
* Merge from Debian unstable (LP: #811976). Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* debian/nut.README.Debian: Adjust udev rules naming for permissions override
  (Closes: #529664)
* Re-add and refresh debian/patches/0001-fix_spelling_and_typo.patch:
  Some typos and spelling errors remain.
* Split nut package into nut-client and nut-server, keep nut package as
  metapackage
* Generate PDF and html doc and install it in nut-doc package
* debian/rules:
  - List non-installed files
  - Includes python-module.mk
  - Add flags to build documentation and install it
* debian/control:
  - Add python-nut package and add python build-dependency
  - Set nut-powerman-pdu priority to extras
  - Add nut-monitor package
  - Add nut-doc package and add required C/R/P
  - Add libups-nut-perl package
* debian/nut-server.prerm: Remove /var/run/nut during removal
* Merge from debian unstable.  Remaining changes:
  - debian/control:
    + Drop Build-Depends on libpowerman0-dev (currently in universe)
  - debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  - debian/rules: Use udev version for Ubuntu.
* debian/patches/backport-fix-lp753661.patch: Refreshed.
* Drop changes due to .pc being not clean.
* New upstream release (Closes: #595953, #614842, #595773)
* debian/patches/*.patch: removed since these are now fixed upstream
* Drop HAL package and build-dependencies (Closes: #613197)
* debian/control:
  - Bump Standards-Version to 3.9.2 (no further changes)
  - Drop autotools build-dependencies (not needed anymore)
  - Drop non-existing build-dependencies
* debian/rules:
  - Correctly pass flags to configure
* Merge from debian unstable (LP: #789323).  Remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to handle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nul-hal-drivers.{docs,install,postinst,preinst}: Dropped since hal is in universe now
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + debian/patches/backport-fix-lp753661.patch
  + Dropped:
    - debian/patches/fix_pc_file.patch: replaced by debian's 0002-fix_libupsclient_pc.patch
* debian/patches/fix_pc_file.patch: add DEP3 patch header
* debian/patches/debian-changes-2.6.0-1: remove that accidental file
* debian/nut-snmp.docs: Distribute snmp.txt doc file (Closes: #548295)
* d/p/0001-fix_spelling_and_typo.patch: Update and refresh
* debian/nut.lintian-overrides: Fix typo
* debian/patch/0002-fix_libupsclient_pc.patch: Fix libupsclient.pc (Closes:
  #624255)
* debian/rules:
  - Switch to cdbs
  - Remove not existing configure options (Closes: #611813)
  - Drop Phony rules (Closes: #613699)
* debian/control:
  - Add cdbs build-dependency
* debian/patches/backport-fix-lp753661.patch: Backport fix 
  to trim extraneous end-of-line, in buggy HID string tables, 
  which results in upsc breaking the communication pipe.
  (LP: #753661)
* fix_pc_file.patch: fix .pc source files by using LIBSSL_LIBS instead of
  LIBSSL_LDFLAGS to avoid a FTBFS in packages that uses libupsclient.pc
  (LP: #743484)
* Merge from Debian unstable, remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nul-hal-drivers.{docs,install,postinst,preinst}: Dropped since hal is in universe now
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + Dropped:
    - debian/patches/0002-fix_udev_action.patch: Accepted upstream.
    - debian/patches/0004-netvision-improvements-lp-600950: no longer needed.
    - debian/patches/0005-fix-nut-m4.patch: no longer needed.
    - debian/patches/9999-autoconf.patch: no longer needed.
* New upstream release (Closes: #575176, #588648, #609597, #687985)
* debian/patches/*.patch: removed since these are now fixed upstream
* debian/patches/0001-fix_spelling_and_typo.patch,
  debian/patches/series: reworked to match the new upstream release
* debian/nut.install, debian/nut.manpages: remove obsolete reference to
  megatec and megatec_usb, now respectively replaced by blazer_ser and
  blazer_usb
* debian/nut.docs: limit distributed documentation
* debian/control:
  - Wrap build-dependencies
  - Change nut-cgi Recommends to apache2 | httpd-cgi
* debian/nut.postinst: Only trigger USB subsystem, should Closes: #574769
* debian/patches/0002-fix_udev_action.patch: Use SUBSYSTEM instead of BUS
* debian/control, debian/rules, 
  debian/nut-hal-drivers.{docs,install,postinst,preinst}: Drop
  nut-hal-drivers since Nut doesnt go into universe.
* Split patches/debian-changes-2.4.3-2ubuntu1 into
  patches/0005-fix-nut-m4.patch and patches/9999-autoconf.patch
* Readd lost debian/patches0004-netvision-improvements-lp-600950.patch patch
  (LP: #707050)
* debian/patches/0002-fix_udev_action.patch:
  Change BUS to SUBSYSTEMS, since the former is deprecated. (LP: #692171)
* debian/nut.postinst: Uncomment missing call to adduser
* debian/control: Drop hal build dependency, we don't need the daemon to
  build the package. Add a hal dependency to nut-hal-drivers, which is the
  only thing that actually needs it.
* Merge from debian unstable.  Remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/nut.postinst: Update udevadm trigger.
    "libusb_get_report: error sending control message: 
     Operation not permitted" error on some UPS devices. (LP: #572262)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + debian/patches/netvision-improvements-lp-600950.patch: Add improvements
    for netvision UPSes
  + Fix FTBFS with ld --as-needed.
  + Dropped:
    - debian/patches/03_udev_rules_change.dpatch: Use debian's instead.
    - debian/patches/04_nut_small-buffers.dpatch: Use debian's instead.
* debian/control:
  - Bump Standards-Version to 3.9.1
  - Update Vcs-* fields to new GIT repository
  - Add myself as Uploaders
* Switch to dpkg-source 3.0 (quilt) format (Closes: #573601)
* debian/patches/0001-low_speed_usb_ups.patch: Use patch system for changes
  that were applied directly in the source
* Add debian/gbp.conf file
* debian/watch: Bump version to 3
* Add debian/patches/0002-fix_udev_action.patch: Also set permission for
  "change" udev ACTION (Closes: #557178)
* debian/nut.postrm: Do not try to remove nut user is deluser is not
  installed anymore
* debian/nut.manpages: Install manpage nut.conf.5 (Closes: #528222)
* debian/copyright: Fix copyright-with-old-dh-make-debian-copyright
* Remove nut-snmp.lintian-overrides, not needed anymore
* debian/patches/0003-fix_spelling_and_typo.patch: Fix some spelling errors
* Add debian/libupsclient1.symbols file
* Add debian/nut.links: Re-add /etc/init.d/ups-monitor that was lost for
  some reasons (Closes: #592351)
* debian/nut.lintian-overrides: Add override for
  init.d-script-does-not-provide-itself /etc/init.d/ups-monitor
* Drop libupsclient1.post{inst,rm}: ldconfig call is added automatically by
  debhelper
* debian/libupsclient1-dev.install: Do not ship /lib/libupsclient.la anymore
* debian/rules: Remove dpatch logic as we are using package source version
  '3.0 (quilt)'
* debian/compat: Bump debhelper compatibility to 8
* Non-maintainer upload.
* drivers/libhid.c: Apply r2407 from upstream to fix bug with some
  low speed UPS devices. (Closes: #583371)
* Fix FTBFS with ld --as-needed.
* debian/patches/netvision-improvements-lp-600950.patch: Add improvements for netvision UPSes 
  (LP: #600950) 
* debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook. 
* debian/patches/04_nut-small-buffers.dpatch: Fix "libusb_get_report: error sending control message: 
  Operation not permitted" error on some UPS devices. (LP: #572262)
* debian/nut.postinst: Revert dropping of --action=change. "add" events must
  not ever be triggered automatically.
* Add 03_udev_rules_change.dpatch: Run udev rules on change events, too.
* debian/control: grr...fix ftbfs. 
* Merge from debian testing.  Remaining changes (LP: #535152):
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/nut.postinst: Update udevadm trigger.
  + Dropped:
    - debian/patches/02-fix-trust-pw4130m.dpatch: No longer needed.
* New upstream release (Closes: #544390, #528222, #539747, #526811,
  #562064)
* debian/nut.install, debian/nut.manpages:
  - remove cyberpower driver and manpage
  - add bestfortress, clone and ivtscd drivers and manpages
* debian/rules:
  - change udev dir to /lib/udev (Closes: #522327)
  - replace deprecated calls to 'dh_clean -k' by dh_prep (Closes: #536599)
* debian/rules, debian/nut.install, debian/nut.install,
  debian/nut.README.Debian: install configuration files, without the
  sample suffix (Closes: #528641)
* debian/nut.links: restored (Closes: #522506)
* debian/nut.init:
  - source nut.conf instead of default/nut for POWEROFF_WAIT(Closes:
    #538173)
  - fix status checking (Closes: #538785)
  - improve detection of non configured system and beautify related
    output (Closes: #563112)
  - use 'invoke-rc.d' instead of calling the reboot script directly
  - add $remote_fs to Required-Start and Required-Stop
* debian/nut.postrm: remove udev files and simplify cleanup (Closes:
  #541629)
* debian/control:
  - remove Luca Filipozzi from the Uploaders list (Closes: #568987)
  - update Standards-Version to 3.8.4
  - remove the debconf dependency
  - bump debhelper version to (>= 7) in Build-Depends, for dh_prep
  - add Breaks on nut-hal-drivers to ensure we have correct udev version
* Remove debconf support since it was related to really old nut
  version (Closes: #518056):
  - remove nut-cgi.config, nut.config, nut-cgi.templates, nut.templates,
    and po/ directory
  - update nut-cgi.postinst
* debian/nut.dirs: remove /var/run/nut to conform to Debian Policy
* debian/nut.postint:
  - create /var/run/nut if needed
  - improve security checks
* debian/nut.README.Debian: add a security note for ups.conf
* debian/watch: URL update
* debian/patches/02-fix-trust-pw4130m.dpatch: Fix issues with Trust
  PW-4130M UPS. (LP: #447586) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
#include "upsclient.h"
28
28
 
 
29
static char             *upsname = NULL, *hostname = NULL;
 
30
static UPSCONN_t        *ups = NULL;
 
31
 
29
32
struct list_t {
30
33
        char    *name;
31
34
        struct  list_t  *next;
33
36
 
34
37
static void usage(const char *prog)
35
38
{
36
 
        printf("Network UPS Tools upsrw %s\n\n", UPS_VERSION);
 
39
        printf("Network UPS Tools %s %s\n\n", prog, UPS_VERSION);
37
40
        printf("usage: %s [-h]\n", prog);
38
41
        printf("       %s [-s <variable>] [-u <username>] [-p <password>] <ups>\n\n", prog);
39
42
        printf("Demo program to set variables within UPS hardware.\n");
47
50
        printf("  <ups>         UPS identifier - <upsname>[@<hostname>[:<port>]]\n");
48
51
        printf("\n");
49
52
        printf("Call without -s to show all possible read/write variables.\n");
50
 
 
51
 
        exit(EXIT_SUCCESS);
52
53
}
53
54
 
54
 
static void clean_exit(UPSCONN_t *ups, char *upsname, char *hostname, int code)
 
55
static void clean_exit(void)
55
56
{
 
57
        if (ups) {
 
58
                upscli_disconnect(ups);
 
59
        }
 
60
 
56
61
        free(upsname);
57
62
        free(hostname);
58
 
 
59
 
        upscli_disconnect(ups);
60
 
 
61
 
        exit(code);
 
63
        free(ups);
62
64
}
63
65
 
64
 
static int do_set(UPSCONN_t *ups, const char *upsname, const char *varname, 
65
 
        const char *newval)
 
66
static void do_set(const char *varname, const char *newval)
66
67
{
67
68
        char    buf[SMALLBUF], enc[SMALLBUF];
68
69
 
69
 
        snprintf(buf, sizeof(buf), "SET VAR %s %s \"%s\"\n",
70
 
                upsname, varname, pconf_encode(newval, enc, sizeof(enc)));
 
70
        snprintf(buf, sizeof(buf), "SET VAR %s %s \"%s\"\n", upsname, varname, pconf_encode(newval, enc, sizeof(enc)));
71
71
 
72
72
        if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
73
 
                fprintf(stderr, "Can't set variable: %s\n", 
74
 
                        upscli_strerror(ups));
75
 
 
76
 
                return EXIT_FAILURE;
 
73
                fatalx(EXIT_FAILURE, "Can't set variable: %s", upscli_strerror(ups));
77
74
        }
78
75
 
79
76
        if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
80
 
                fprintf(stderr, "Set variable failed: %s\n", 
81
 
                        upscli_strerror(ups));
82
 
 
83
 
                return EXIT_FAILURE;
 
77
                fatalx(EXIT_FAILURE, "Set variable failed: %s", upscli_strerror(ups));
84
78
        }
85
79
 
86
80
        /* FUTURE: status cookies will tie in here */
87
81
        if (strncmp(buf, "OK", 2) != 0) {
88
 
                printf("Unexpected response from upsd: %s\n", buf);
89
 
                return EXIT_FAILURE;
 
82
                fatalx(EXIT_FAILURE, "Unexpected response from upsd: %s", buf);
90
83
        }
91
84
 
92
 
        return EXIT_SUCCESS;
 
85
        fprintf(stderr, "%s\n", buf);
93
86
}
94
87
 
95
 
static int do_setvar(UPSCONN_t *ups, const char *varname, char *uin,
96
 
                const char *pass, char *upsname, char *hostname)
 
88
static void do_setvar(const char *varname, char *uin, const char *pass)
97
89
{
98
90
        char    newval[SMALLBUF], temp[SMALLBUF], user[SMALLBUF], *ptr;
99
 
        struct  passwd  *pw;
 
91
        struct passwd   *pw;
100
92
 
101
93
        if (uin) {
102
94
                snprintf(user, sizeof(user), "%s", uin);
105
97
 
106
98
                pw = getpwuid(getuid());
107
99
 
108
 
                if (pw)
 
100
                if (pw) {
109
101
                        printf("Username (%s): ", pw->pw_name);
110
 
                else
 
102
                } else {
111
103
                        printf("Username: ");
 
104
                }
112
105
 
113
106
                if (fgets(user, sizeof(user), stdin) == NULL) {
114
107
                        upsdebug_with_errno(LOG_INFO, "%s", __func__);
115
108
                }
116
109
 
117
110
                /* deal with that pesky newline */
118
 
                if (strlen(user) > 1)
 
111
                if (strlen(user) > 1) {
119
112
                        user[strlen(user) - 1] = '\0';
120
 
                else {
121
 
                        if (!pw)
 
113
                } else {
 
114
                        if (!pw) {
122
115
                                fatalx(EXIT_FAILURE, "No username available - even tried getpwuid");
123
 
        
 
116
                        }
 
117
 
124
118
                        snprintf(user, sizeof(user), "%s", pw->pw_name);
125
119
                }
126
120
        }
130
124
                pass = GETPASS("Password: " );
131
125
 
132
126
                if (!pass) {
133
 
                        fprintf(stderr, "getpass failed: %s\n", 
134
 
                                strerror(errno));
135
 
 
136
 
                        return EXIT_FAILURE;
 
127
                        fatal_with_errno(EXIT_FAILURE, "getpass failed");
137
128
                }
138
129
        }
139
130
 
153
144
        snprintf(temp, sizeof(temp), "USERNAME %s\n", user);
154
145
 
155
146
        if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
156
 
                fprintf(stderr, "Can't set username: %s\n", 
157
 
                        upscli_strerror(ups));
158
 
 
159
 
                return EXIT_FAILURE;
 
147
                fatalx(EXIT_FAILURE, "Can't set username: %s", upscli_strerror(ups));
160
148
        }
161
149
 
162
150
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
163
151
 
164
152
                if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
165
 
                        fprintf(stderr, "Set username failed due to an "
166
 
                                "unknown command.\n");
167
 
 
168
 
                        fprintf(stderr, "You probably need to upgrade upsd.\n");
169
 
 
170
 
                        clean_exit(ups, upsname, hostname, EXIT_FAILURE);
 
153
                        fatalx(EXIT_FAILURE, "Set username failed due to an unknown command. You probably need to upgrade upsd.");
171
154
                }
172
155
 
173
 
                fprintf(stderr, "Set username failed: %s\n",
174
 
                        upscli_strerror(ups));
175
 
 
176
 
                return EXIT_FAILURE;
 
156
                fatalx(EXIT_FAILURE, "Set username failed: %s", upscli_strerror(ups));
177
157
        }
178
158
 
179
159
        snprintf(temp, sizeof(temp), "PASSWORD %s\n", pass);
180
160
 
181
161
        if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
182
 
                fprintf(stderr, "Can't set password: %s\n", 
183
 
                        upscli_strerror(ups));
184
 
 
185
 
                return EXIT_FAILURE;
 
162
                fatalx(EXIT_FAILURE, "Can't set password: %s", upscli_strerror(ups));
186
163
        }
187
164
 
188
165
        if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
189
 
                fprintf(stderr, "Set password failed: %s\n", 
190
 
                        upscli_strerror(ups));
191
 
 
192
 
                return EXIT_FAILURE;
 
166
                fatalx(EXIT_FAILURE, "Set password failed: %s", upscli_strerror(ups));
193
167
        }
194
168
 
195
169
        /* no upsname means die */
196
170
        if (!upsname) {
197
 
                fprintf(stderr, "Error: a UPS name must be specified (upsname[@hostname[:port]])\n");
198
 
                return EXIT_FAILURE;
 
171
                fatalx(EXIT_FAILURE, "Error: a UPS name must be specified (upsname[@hostname[:port]])");
199
172
        }
200
173
 
201
174
        /* old variable names are no longer supported */
202
175
        if (!strchr(varname, '.')) {
203
 
                fprintf(stderr, "Error: old variable names are not supported\n");
204
 
                return EXIT_FAILURE;
 
176
                fatalx(EXIT_FAILURE, "Error: old variable names are not supported");
205
177
        }
206
178
 
207
 
        return do_set(ups, upsname, varname, newval);
208
 
}       
 
179
        do_set(varname, newval);
 
180
}
209
181
 
210
 
static const char *get_data(const char *type, UPSCONN_t *ups, 
211
 
        const char *upsname, const char *varname)
 
182
static const char *get_data(const char *type, const char *varname)
212
183
{
213
184
        int     ret;
214
185
        unsigned int    numq, numa;
215
186
        char    **answer;
216
 
        const   char    *query[4];
 
187
        const char      *query[4];
217
188
 
218
189
        query[0] = type;
219
190
        query[1] = upsname;
220
191
        query[2] = varname;
 
192
 
221
193
        numq = 3;
222
194
 
223
195
        ret = upscli_get(ups, numq, query, &numa, &answer);
224
196
 
225
 
        if ((ret < 0) || (numa < numq))
 
197
        if ((ret < 0) || (numa < numq)) {
226
198
                return NULL;
 
199
        }
227
200
 
228
201
        /* <type> <upsname> <varname> <desc> */
229
202
        return answer[3];
230
203
}
231
204
 
232
 
static void do_string(UPSCONN_t *ups, const char *upsname, const char *varname)
 
205
static void do_string(const char *varname)
233
206
{
234
 
        const   char    *val;
 
207
        const char      *val;
235
208
 
236
 
        val = get_data("VAR", ups, upsname, varname);
 
209
        val = get_data("VAR", varname);
237
210
 
238
211
        if (!val) {
239
 
                fprintf(stderr, "do_string: can't get current value of %s\n",
240
 
                        varname);
241
 
                return;
 
212
                fatalx(EXIT_FAILURE, "do_string: can't get current value of %s", varname);
242
213
        }
243
214
 
244
215
        printf("Type: STRING\n");
245
216
        printf("Value: %s\n", val);
246
217
}
247
218
 
248
 
static void do_enum(UPSCONN_t *ups, const char *upsname, const char *varname)
 
219
static void do_enum(const char *varname)
249
220
{
250
221
        int     ret;
251
222
        unsigned int    numq, numa;
252
 
        char    **answer, *val;
253
 
        const   char    *query[4], *tmp;
 
223
        char    **answer, buf[SMALLBUF];
 
224
        const char      *query[4], *val;
254
225
 
255
226
        /* get current value */
256
 
        tmp = get_data("VAR", ups, upsname, varname);
 
227
        val = get_data("VAR", varname);
257
228
 
258
 
        if (!tmp) {
259
 
                fprintf(stderr, "do_enum: can't get current value of %s\n",
260
 
                        varname);
261
 
                return;
 
229
        if (!val) {
 
230
                fatalx(EXIT_FAILURE, "do_enum: can't get current value of %s", varname);
262
231
        }
263
232
 
264
 
        /* tmp is a pointer into answer - have to save it somewhere else */
265
 
        val = xstrdup(tmp);
 
233
        snprintf(buf, sizeof(buf), "%s", val);
266
234
 
267
235
        query[0] = "ENUM";
268
236
        query[1] = upsname;
272
240
        ret = upscli_list_start(ups, numq, query);
273
241
 
274
242
        if (ret < 0) {
275
 
                fprintf(stderr, "Error: %s\n", upscli_strerror(ups));
276
 
                return;
 
243
                fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
277
244
        }
278
245
 
279
246
        ret = upscli_list_next(ups, numq, query, &numa, &answer);
285
252
                /* ENUM <upsname> <varname> <value> */
286
253
 
287
254
                if (numa < 4) {
288
 
                        fprintf(stderr, "Error: insufficient data "
289
 
                                "(got %d args, need at least 4)\n", numa);
290
 
 
291
 
                        free(val);
292
 
                        return;
 
255
                        fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
293
256
                }
294
257
 
295
258
                printf("Option: \"%s\"", answer[3]);
296
259
 
297
 
                if (!strcmp(answer[3], val))
298
 
                        printf(" SELECTED");
299
 
 
300
 
                printf("\n");
301
 
 
302
 
                ret = upscli_list_next(ups, numq, query, &numa, &answer);
303
 
        }
304
 
 
305
 
        free(val);
306
 
}
307
 
 
308
 
static void do_type(UPSCONN_t *ups, const char *upsname, const char *varname)
 
260
                if (!strcmp(answer[3], buf)) {
 
261
                        printf(" SELECTED");
 
262
                }
 
263
 
 
264
                printf("\n");
 
265
 
 
266
                ret = upscli_list_next(ups, numq, query, &numa, &answer);
 
267
        }
 
268
}
 
269
 
 
270
static void do_range(const char *varname)
 
271
{
 
272
        int     ret;
 
273
        unsigned int    numq, numa;
 
274
        char    **answer;
 
275
        const char      *query[4], *val;
 
276
        int ival, min, max;
 
277
 
 
278
        /* get current value */
 
279
        val = get_data("VAR", varname);
 
280
 
 
281
        if (!val) {
 
282
                fatalx(EXIT_FAILURE, "do_range: can't get current value of %s", varname);
 
283
        }
 
284
 
 
285
        ival = atoi(val);
 
286
 
 
287
        query[0] = "RANGE";
 
288
        query[1] = upsname;
 
289
        query[2] = varname;
 
290
        numq = 3;
 
291
 
 
292
        ret = upscli_list_start(ups, numq, query);
 
293
 
 
294
        if (ret < 0) {
 
295
                fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
 
296
        }
 
297
 
 
298
        ret = upscli_list_next(ups, numq, query, &numa, &answer);
 
299
 
 
300
        printf("Type: RANGE\n");
 
301
 
 
302
        while (ret == 1) {
 
303
 
 
304
                /* RANGE <upsname> <varname> <min> <max> */
 
305
 
 
306
                if (numa < 5) {
 
307
                        fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
 
308
                }
 
309
 
 
310
                min = atoi(answer[3]);
 
311
                max = atoi(answer[4]);
 
312
 
 
313
                printf("Option: \"%i-%i\"", min, max);
 
314
 
 
315
                if ((ival >= min) && (ival <= max)) {
 
316
                        printf(" SELECTED");
 
317
                }
 
318
 
 
319
                printf("\n");
 
320
 
 
321
                ret = upscli_list_next(ups, numq, query, &numa, &answer);
 
322
        }
 
323
}
 
324
 
 
325
static void do_type(const char *varname)
309
326
{
310
327
        int     ret;
311
328
        unsigned int    i, numq, numa;
312
329
        char    **answer;
313
 
        const   char    *query[4];
 
330
        const char      *query[4];
314
331
 
315
332
        query[0] = "TYPE";
316
333
        query[1] = upsname;
328
345
        for (i = 3; i < numa; i++) {
329
346
 
330
347
                if (!strcasecmp(answer[i], "ENUM")) {
331
 
                        do_enum(ups, upsname, varname);
 
348
                        do_enum(varname);
 
349
                        return;
 
350
                }
 
351
 
 
352
                if (!strcasecmp(answer[i], "RANGE")) {
 
353
                        do_range(varname);
332
354
                        return;
333
355
                }
334
356
 
335
357
                if (!strncasecmp(answer[i], "STRING:", 7)) {
336
 
                        do_string(ups, upsname, varname);
 
358
                        do_string(varname);
337
359
                        return;
338
360
                }
339
361
 
340
362
                /* ignore this one */
341
 
                if (!strcasecmp(answer[i], "RW"))
 
363
                if (!strcasecmp(answer[i], "RW")) {
342
364
                        continue;
 
365
                }
343
366
 
344
367
                printf("Type: %s (unrecognized)\n", answer[i]);
345
368
        }
346
 
 
347
369
}
348
370
 
349
 
static void print_rw(UPSCONN_t *ups, const char *upsname, const char *varname)
 
371
static void print_rw(const char *varname)
350
372
{
351
 
        const   char    *tmp;
 
373
        const char      *tmp;
352
374
 
353
375
        printf("[%s]\n", varname);
354
376
 
355
 
        tmp = get_data("DESC", ups, upsname, varname);
 
377
        tmp = get_data("DESC", varname);
356
378
 
357
 
        if (tmp)
 
379
        if (tmp) {
358
380
                printf("%s\n", tmp);
359
 
        else
 
381
        } else {
360
382
                printf("Description unavailable\n");
 
383
        }
361
384
 
362
 
        do_type(ups, upsname, varname);
 
385
        do_type(varname);
363
386
 
364
387
        printf("\n");
365
 
}       
 
388
}
366
389
 
367
 
static int print_rwlist(UPSCONN_t *ups, const char *upsname)
 
390
static void print_rwlist(void)
368
391
{
369
392
        int     ret;
370
393
        unsigned int    numq, numa;
371
 
        const   char    *query[2];
 
394
        const char      *query[2];
372
395
        char    **answer;
373
396
        struct  list_t  *lhead, *llast, *ltmp, *lnext;
374
397
 
375
398
        /* the upsname is now required */
376
399
        if (!upsname) {
377
 
                fprintf(stderr, "Error: a UPS name must be specified (upsname[@hostname[:port]])\n");
378
 
                return EXIT_FAILURE;
 
400
                fatalx(EXIT_FAILURE, "Error: a UPS name must be specified (upsname[@hostname[:port]])");
379
401
        }
380
402
 
381
403
        llast = lhead = NULL;
390
412
 
391
413
                /* old upsd --> fall back on old LISTRW technique */
392
414
                if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
393
 
                        fprintf(stderr, "Error: upsd is too old to support this query\n");
394
 
                        return EXIT_FAILURE;
 
415
                        fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query");
395
416
                }
396
417
 
397
 
                fprintf(stderr, "Error: %s\n", upscli_strerror(ups));
398
 
                return EXIT_FAILURE;
 
418
                fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
399
419
        }
400
420
 
401
421
        ret = upscli_list_next(ups, numq, query, &numa, &answer);
404
424
 
405
425
                /* RW <upsname> <varname> <value> */
406
426
                if (numa < 4) {
407
 
                        fprintf(stderr, "Error: insufficient data "
408
 
                                "(got %d args, need at least 4)\n", numa);
409
 
                        return EXIT_FAILURE;
 
427
                        fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
410
428
                }
411
429
 
412
430
                /* sock this entry away for later */
415
433
                ltmp->name = xstrdup(answer[2]);
416
434
                ltmp->next = NULL;
417
435
 
418
 
                if (llast)
 
436
                if (llast) {
419
437
                        llast->next = ltmp;
420
 
                else
 
438
                } else {
421
439
                        lhead = ltmp;
 
440
                }
422
441
 
423
442
                llast = ltmp;
424
443
 
432
451
        while (ltmp) {
433
452
                lnext = ltmp->next;
434
453
 
435
 
                print_rw(ups, upsname, ltmp->name);
 
454
                print_rw(ltmp->name);
436
455
 
437
456
                free(ltmp->name);
438
457
                free(ltmp);
439
458
                ltmp = lnext;
440
459
        }
441
 
 
442
 
        return EXIT_SUCCESS;
443
460
}
444
461
 
445
462
int main(int argc, char **argv)
446
463
{
447
 
        int     i, port, ret;
448
 
        char    *upsname, *hostname, *setvar, *prog;
449
 
        char    *password = NULL, *username = NULL;
450
 
        UPSCONN_t       ups;
451
 
 
452
 
        setvar = username = NULL;
453
 
        prog = argv[0];
454
 
 
455
 
        while ((i = getopt(argc, argv, "+s:p:u:V")) != -1) {
456
 
                switch (i) {
 
464
        int     i, port;
 
465
        const char      *prog = xbasename(argv[0]);
 
466
        char    *password = NULL, *username = NULL, *setvar = NULL;
 
467
 
 
468
        while ((i = getopt(argc, argv, "+hs:p:u:V")) != -1) {
 
469
                switch (i)
 
470
                {
457
471
                case 's':
458
472
                        setvar = optarg;
459
473
                        break;
464
478
                        username = optarg;
465
479
                        break;
466
480
                case 'V':
467
 
                        printf("Network UPS Tools upsrw %s\n", UPS_VERSION);
 
481
                        printf("Network UPS Tools %s %s\n", prog, UPS_VERSION);
468
482
                        exit(EXIT_SUCCESS);
 
483
                case 'h':
469
484
                default:
470
485
                        usage(prog);
471
 
                        break;
 
486
                        exit(EXIT_SUCCESS);
472
487
                }
473
488
        }
474
489
 
475
490
        argc -= optind;
476
491
        argv += optind;
477
492
 
478
 
        if (argc < 1)
 
493
        if (argc < 1) {
479
494
                usage(prog);
 
495
                exit(EXIT_SUCCESS);
 
496
        }
480
497
 
481
 
        upsname = hostname = NULL;
 
498
        /* be a good little client that cleans up after itself */
 
499
        atexit(clean_exit);
482
500
 
483
501
        if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0) {
484
 
                fprintf(stderr, "Error: invalid UPS definition.  Required format: upsname[@hostname[:port]]\n");
485
 
                clean_exit(&ups, upsname, hostname, EXIT_FAILURE);
486
 
        }
487
 
 
488
 
        if (upscli_connect(&ups, hostname, port, 0) < 0) {
489
 
                fprintf(stderr, "Can't connect: %s\n", upscli_strerror(&ups));
490
 
                clean_exit(&ups, upsname, hostname, EXIT_FAILURE);
491
 
        }
492
 
 
493
 
        /* setting a variable? */
 
502
                fatalx(EXIT_FAILURE, "Error: invalid UPS definition.  Required format: upsname[@hostname[:port]]");
 
503
        }
 
504
 
 
505
        ups = xcalloc(1, sizeof(*ups));
 
506
 
 
507
        if (upscli_connect(ups, hostname, port, 0) < 0) {
 
508
                fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
 
509
        }
 
510
 
494
511
        if (setvar) {
495
 
                ret = do_setvar(&ups, setvar, username, password, upsname,
496
 
                        hostname);
497
 
 
498
 
                clean_exit(&ups, upsname, hostname, ret);
 
512
                /* setting a variable */
 
513
                do_setvar(setvar, username, password);
 
514
        } else {
 
515
                /* if not, get the list of supported read/write variables */
 
516
                print_rwlist();
499
517
        }
500
518
 
501
 
        /* if not, get the list of supported read/write variables */
502
 
        ret = print_rwlist(&ups, upsname);
503
 
 
504
 
        clean_exit(&ups, upsname, hostname, ret);
505
 
 
506
 
        /* NOTREACHED */
507
 
        exit(EXIT_FAILURE);
 
519
        exit(EXIT_SUCCESS);
508
520
}