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

« back to all changes in this revision

Viewing changes to server/upsd.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:
1
1
/* upsd.c - watches ups state files and answers queries 
2
2
 
3
3
   Copyright (C)
4
 
        1999    Russell Kroll <rkroll@exploits.org>
5
 
        2008    Arjen de Korte <adkorte-guest@alioth.debian.org>
 
4
        1999            Russell Kroll <rkroll@exploits.org>
 
5
        2008            Arjen de Korte <adkorte-guest@alioth.debian.org>
 
6
        2011 - 2012     Arnaud Quette <arnaud.quette.free.fr>
6
7
 
7
8
   This program is free software; you can redistribute it and/or modify
8
9
   it under the terms of the GNU General Public License as published by
32
33
#include <poll.h>
33
34
 
34
35
#include "user.h"
35
 
#include "ctype.h"
 
36
#include "nut_ctype.h"
36
37
#include "stype.h"
37
38
#include "ssl.h"
38
39
#include "sstate.h"
52
53
        /* default 15 seconds before data is marked stale */
53
54
        int     maxage = 15;
54
55
 
55
 
        /* default FD_SETSIZE connections allowed */
56
 
        int     maxconn = FD_SETSIZE;
 
56
        /* preloaded to {OPEN_MAX} in main, can be overridden via upsd.conf */
 
57
        int     maxconn = 0;
57
58
 
58
59
        /* preloaded to STATEPATH in main, can be overridden via upsd.conf */
59
60
        char    *statepath = NULL;
64
65
        /* everything else */
65
66
        const char      *progname;
66
67
 
67
 
static ctype_t  *firstclient = NULL;
68
 
/* static ctype_t       *lastclient = NULL; */
 
68
nut_ctype_t     *firstclient = NULL;
 
69
/* static nut_ctype_t   *lastclient = NULL; */
69
70
 
70
71
        /* default is to listen on all local interfaces */
71
72
static stype_t  *firstaddr = NULL;
72
73
 
73
 
#ifdef  HAVE_IPV6
74
74
static int      opt_af = AF_UNSPEC;
75
 
#endif
76
75
 
77
76
typedef enum {
78
77
        DRIVER = 1,
95
94
        /* set by signal handlers */
96
95
static int      reload_flag = 0, exit_flag = 0;
97
96
 
98
 
#ifdef  HAVE_IPV6
99
97
static const char *inet_ntopW (struct sockaddr_storage *s)
100
98
{
101
99
        static char str[40];
111
109
                return NULL;
112
110
        }
113
111
}
114
 
#endif
115
112
 
116
113
/* return a pointer to the named ups if possible */
117
114
upstype_t *get_ups_ptr(const char *name)
181
178
/* create a listening socket for tcp connections */
182
179
static void setuptcp(stype_t *server)
183
180
{
184
 
#ifndef HAVE_IPV6
185
 
        struct hostent          *host;
186
 
        struct sockaddr_in      sockin;
187
 
        int     res, one = 1;
188
 
 
189
 
        host = gethostbyname(server->addr);
190
 
 
191
 
        if (!host) {
192
 
                struct  in_addr listenaddr;
193
 
 
194
 
                if (!inet_aton(server->addr, &listenaddr)) {
195
 
                        fatal_with_errno(EXIT_FAILURE, "inet_aton");
196
 
                }
197
 
 
198
 
                host = gethostbyaddr(&listenaddr, sizeof(listenaddr), AF_INET);
199
 
 
200
 
                if (!host) {
201
 
                        fatal_with_errno(EXIT_FAILURE, "gethostbyaddr");
202
 
                }
203
 
        }
204
 
 
205
 
        if ((server->sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
206
 
                fatal_with_errno(EXIT_FAILURE, "socket");
207
 
        }
208
 
 
209
 
        res = setsockopt(server->sock_fd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
210
 
 
211
 
        if (res != 0) {
212
 
                fatal_with_errno(EXIT_FAILURE, "setsockopt(SO_REUSEADDR)");
213
 
        }
214
 
 
215
 
        memset(&sockin, '\0', sizeof(sockin));
216
 
        sockin.sin_family = AF_INET;
217
 
        sockin.sin_port = htons(atoi(server->port));
218
 
 
219
 
        memcpy(&sockin.sin_addr, host->h_addr, host->h_length);
220
 
 
221
 
        if (bind(server->sock_fd, (struct sockaddr *) &sockin, sizeof(sockin)) == -1) {
222
 
                fatal_with_errno(EXIT_FAILURE, "Can't bind TCP port %s", server->port);
223
 
        }
224
 
 
225
 
        if ((res = fcntl(server->sock_fd, F_GETFL, 0)) == -1) {
226
 
                fatal_with_errno(EXIT_FAILURE, "fcntl(get)");
227
 
        }
228
 
 
229
 
        if (fcntl(server->sock_fd, F_SETFL, res | O_NDELAY) == -1) {
230
 
                fatal_with_errno(EXIT_FAILURE, "fcntl(set)");
231
 
        }
232
 
 
233
 
        if (listen(server->sock_fd, 16)) {
234
 
                fatal_with_errno(EXIT_FAILURE, "listen");
235
 
        }
236
 
#else
237
181
        struct addrinfo         hints, *res, *ai;
238
182
        int     v = 0, one = 1;
239
183
 
290
234
        }
291
235
 
292
236
        freeaddrinfo(res);
293
 
#endif
294
237
 
295
 
        /* don't fail silently */
 
238
        /* leave up to the caller, server_load(), to fail silently if there is
 
239
         * no other valid LISTEN interface */
296
240
        if (server->sock_fd < 0) {
297
 
                fatalx(EXIT_FAILURE, "not listening on %s port %s", server->addr, server->port);
 
241
                upslogx(LOG_ERR, "not listening on %s port %s", server->addr, server->port);
298
242
        } else {
299
243
                upslogx(LOG_INFO, "listening on %s port %s", server->addr, server->port);
300
244
        }
322
266
}
323
267
 
324
268
/* disconnect a client connection and free all related memory */
325
 
static void client_disconnect(ctype_t *client)
 
269
static void client_disconnect(nut_ctype_t *client)
326
270
{
327
271
        if (!client) {
328
272
                return;
365
309
}
366
310
 
367
311
/* send the buffer <sendbuf> of length <sendlen> to host <dest> */
368
 
int sendback(ctype_t *client, const char *fmt, ...)
 
312
int sendback(nut_ctype_t *client, const char *fmt, ...)
369
313
{
370
314
        int     res, len;
371
315
        char ans[NUT_NET_ANSWER_MAX+1];
399
343
}
400
344
 
401
345
/* just a simple wrapper for now */
402
 
int send_err(ctype_t *client, const char *errtype)
 
346
int send_err(nut_ctype_t *client, const char *errtype)
403
347
{
404
348
        if (!client) {
405
349
                return -1;
413
357
/* disconnect anyone logged into this UPS */
414
358
void kick_login_clients(const char *upsname)
415
359
{
416
 
        ctype_t *client, *cnext;
 
360
        nut_ctype_t     *client, *cnext;
417
361
 
418
362
        for (client = firstclient; client; client = cnext) {
419
363
 
432
376
}
433
377
 
434
378
/* make sure a UPS is sane - connected, with fresh data */
435
 
int ups_available(const upstype_t *ups, ctype_t *client)
 
379
int ups_available(const upstype_t *ups, nut_ctype_t *client)
436
380
{
437
381
        if (ups->sock_fd < 0) {
438
382
                send_err(client, NUT_ERR_DRIVER_NOT_CONNECTED);
449
393
}
450
394
 
451
395
/* check flags and access for an incoming command from the network */
452
 
static void check_command(int cmdnum, ctype_t *client, int numarg, 
 
396
static void check_command(int cmdnum, nut_ctype_t *client, int numarg, 
453
397
        const char **arg)
454
398
{
455
399
        if (netcmds[cmdnum].flags & FLAG_USER) {
468
412
                }
469
413
 
470
414
#ifdef HAVE_WRAP
471
 
                request_init(&req, RQ_DAEMON, progname, RQ_CLIENT_ADDR, client->addr, RQ_USER, client->username, 0);
 
415
                request_init(&req, RQ_DAEMON, progname, RQ_FILE, client->sock_fd, RQ_USER, client->username, 0);
 
416
                fromhost(&req);
472
417
 
473
418
                if (!hosts_access(&req)) {
474
419
                        /* tcp-wrappers says access should be denied */
483
428
}
484
429
 
485
430
/* parse requests from the network */
486
 
static void parse_net(ctype_t *client)
 
431
static void parse_net(nut_ctype_t *client)
487
432
{
488
433
        int     i;
489
434
 
508
453
/* answer incoming tcp connections */
509
454
static void client_connect(stype_t *server)
510
455
{
511
 
#ifndef HAVE_IPV6
512
 
        struct  sockaddr_in csock;
513
 
#else
514
456
        struct  sockaddr_storage csock;
515
 
#endif
 
457
#if defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED) 
 
458
        int     clen;
 
459
#else
516
460
        socklen_t       clen;
 
461
#endif
517
462
        int             fd;
518
 
        ctype_t         *client;
 
463
        nut_ctype_t             *client;
519
464
 
520
465
        clen = sizeof(csock);
521
466
        fd = accept(server->sock_fd, (struct sockaddr *) &csock, &clen);
530
475
 
531
476
        time(&client->last_heard);
532
477
 
533
 
#ifndef HAVE_IPV6
534
 
        client->addr = xstrdup(inet_ntoa(csock.sin_addr));
535
 
#else
536
478
        client->addr = xstrdup(inet_ntopW(&csock));
537
 
#endif
538
479
 
539
480
        pconf_init(&client->ctx, NULL);
540
481
 
557
498
}
558
499
 
559
500
/* read tcp messages and handle them */
560
 
static void client_readline(ctype_t *client)
 
501
static void client_readline(nut_ctype_t *client)
561
502
{
562
503
        char    buf[SMALLBUF];
563
504
        int     i, ret;
610
551
 
611
552
        /* default behaviour if no LISTEN addres has been specified */
612
553
        if (!firstaddr) {
613
 
#ifdef  HAVE_IPV6
614
554
                if (opt_af != AF_INET) {
615
555
                        listen_add("::1", string_const(PORT));
616
556
                }
618
558
                if (opt_af != AF_INET6) {
619
559
                        listen_add("127.0.0.1", string_const(PORT));
620
560
                }
621
 
#else
622
 
                listen_add("127.0.0.1", string_const(PORT));
623
 
#endif
624
561
        }
625
562
 
626
563
        for (server = firstaddr; server; server = server->next) {
627
564
                setuptcp(server);
628
565
        }
 
566
        
 
567
        /* check if we have at least 1 valid LISTEN interface */
 
568
        if (firstaddr->sock_fd < 0) {
 
569
                fatalx(EXIT_FAILURE, "no listening interface available");
 
570
        }
629
571
}
630
572
 
631
573
void server_free(void)
650
592
 
651
593
static void client_free(void)
652
594
{
653
 
        ctype_t         *client, *cnext;
 
595
        nut_ctype_t             *client, *cnext;
654
596
 
655
597
        /* cleanup client fds */
656
598
        for (client = firstclient; client; client = cnext) {
712
654
        ret = sysconf(_SC_OPEN_MAX);
713
655
 
714
656
        if (ret < maxconn) {
715
 
                fatalx(EXIT_FAILURE, "Maximum number of connections limited to %d [requested %d]", ret, maxconn);
 
657
                fatalx(EXIT_FAILURE,
 
658
                        "Your system limits the maximum number of connections to %d\n"
 
659
                        "but you requested %d. The server won't start until this\n"
 
660
                        "problem is resolved.\n", ret, maxconn);
716
661
        }
717
662
 
718
663
        fds = xrealloc(fds, maxconn * sizeof(*fds));
725
670
        int     i, ret, nfds = 0;
726
671
 
727
672
        upstype_t       *ups;
728
 
        ctype_t         *client, *cnext;
 
673
        nut_ctype_t             *client, *cnext;
729
674
        stype_t         *server;
730
675
        time_t  now;
731
676
 
827
772
                                sstate_disconnect((upstype_t *)handler[i].data);
828
773
                                break;
829
774
                        case CLIENT:
830
 
                                client_disconnect((ctype_t *)handler[i].data);
 
775
                                client_disconnect((nut_ctype_t *)handler[i].data);
831
776
                                break;
832
777
                        case SERVER:
833
778
                                upsdebugx(2, "%s: server disconnected", __func__);
848
793
                                sstate_readline((upstype_t *)handler[i].data);
849
794
                                break;
850
795
                        case CLIENT:
851
 
                                client_readline((ctype_t *)handler[i].data);
 
796
                                client_readline((nut_ctype_t *)handler[i].data);
852
797
                                break;
853
798
                        case SERVER:
854
799
                                client_connect((stype_t *)handler[i].data);
876
821
        printf("  -D            raise debugging level\n");
877
822
        printf("  -h            display this help\n");
878
823
        printf("  -r <dir>      chroots to <dir>\n");
 
824
        printf("  -q            raise log level threshold\n");
879
825
        printf("  -u <user>     switch to <user> (if started as root)\n");
880
826
        printf("  -V            display the version of this software\n");
881
 
#ifdef  HAVE_IPV6
882
827
        printf("  -4            IPv4 only\n");
883
828
        printf("  -6            IPv6 only\n");
884
 
#endif
885
829
 
886
830
        exit(EXIT_SUCCESS);
887
831
}
940
884
{
941
885
        int     i, cmd = 0;
942
886
        char    *chroot_path = NULL;
943
 
        const char      *user = NULL;
 
887
        const char      *user = RUN_AS_USER;
944
888
        struct passwd   *new_uid = NULL;
945
889
 
946
890
        progname = xbasename(argv[0]);
947
891
 
948
 
        /* pick up a default from configure --with-user */
949
 
        user = RUN_AS_USER;
950
 
 
951
892
        /* yes, xstrdup - the conf handlers call free on this later */
952
893
        statepath = xstrdup(dflt_statepath());
953
894
        datapath = xstrdup(DATADIR);
954
895
 
955
896
        /* set up some things for later */
956
 
        snprintf(pidfn, sizeof(pidfn), "%s/upsd.pid", altpidpath());
957
 
 
958
 
        printf("Network UPS Tools upsd %s\n", UPS_VERSION);
959
 
 
960
 
        while ((i = getopt(argc, argv, "+h46p:r:i:fu:Vc:D")) != -1) {
 
897
        snprintf(pidfn, sizeof(pidfn), "%s/%s.pid", altpidpath(), progname);
 
898
 
 
899
        printf("Network UPS Tools %s %s\n", progname, UPS_VERSION);
 
900
 
 
901
        while ((i = getopt(argc, argv, "+h46p:qr:i:fu:Vc:D")) != -1) {
961
902
                switch (i) {
962
903
                        case 'h':
963
904
                                help(progname);
967
908
                                fatalx(EXIT_FAILURE, "Specifying a listening addresses with '-i <address>' and '-p <port>'\n"
968
909
                                        "is deprecated. Use 'LISTEN <address> [<port>]' in 'upsd.conf' instead.\n"
969
910
                                        "See 'man 8 upsd.conf' for more information.");
 
911
                        case 'q':
 
912
                                nut_log_level++;
 
913
                                break;
970
914
                        case 'r':
971
915
                                chroot_path = optarg;
972
916
                                break;
974
918
                                user = optarg;
975
919
                                break;
976
920
                        case 'V':
977
 
 
978
921
                                /* do nothing - we already printed the banner */
979
922
                                exit(EXIT_SUCCESS);
980
923
 
993
936
                                nut_debug_level++;
994
937
                                break;
995
938
 
996
 
#ifdef  HAVE_IPV6
997
 
                  case '4':
 
939
                        case '4':
998
940
                                opt_af = AF_INET;
999
941
                                break;
1000
942
 
1001
 
                  case '6':
 
943
                        case '6':
1002
944
                                opt_af = AF_INET6;
1003
945
                                break;
1004
 
#endif
1005
946
 
1006
947
                        default:
1007
948
                                help(progname);
1014
955
                exit(EXIT_SUCCESS);
1015
956
        }
1016
957
 
 
958
        /* otherwise, we are being asked to start.
 
959
         * so check if a previous instance is running by sending signal '0'
 
960
         * (Ie 'kill <pid> 0') */
 
961
        if (sendsignalfn(pidfn, 0) == 0) {
 
962
                printf("Fatal error: A previous upsd instance is already running!\n");
 
963
                printf("Either stop the previous instance first, or use the 'reload' command.\n");
 
964
                exit(EXIT_FAILURE);
 
965
        }
 
966
 
1017
967
        argc -= optind;
1018
968
        argv += optind;
1019
969
 
1025
975
 
1026
976
        setup_signals();
1027
977
 
1028
 
        open_syslog("upsd");
 
978
        open_syslog(progname);
1029
979
 
1030
980
        /* send logging to the syslog pre-background for later use */
1031
981
        syslogbit_set();
1037
987
                chroot_start(chroot_path);
1038
988
        }
1039
989
 
 
990
        /* default to system limit (may be overridden in upsd.conf */
 
991
        maxconn = sysconf(_SC_OPEN_MAX);
 
992
 
1040
993
        /* handle upsd.conf */
1041
994
        load_upsdconf(0);       /* 0 = initial */
1042
995
 
1043
996
        /* start server */
1044
997
        server_load();
1045
998
 
 
999
        /* initialize SSL before we drop privileges (we may not be able to read the keyfile as non-root) */
 
1000
        ssl_init();
 
1001
 
1046
1002
        become_user(new_uid);
1047
1003
 
1048
1004
        if (chdir(statepath)) {
1061
1017
                fatalx(EXIT_FAILURE, "Fatal error: at least one UPS must be defined in ups.conf");
1062
1018
        }
1063
1019
 
1064
 
        ssl_init();
1065
 
 
1066
1020
        /* try to bring in the var/cmd descriptions */
1067
1021
        desc_load();
1068
1022
 
1083
1037
        upslogx(LOG_INFO, "Signal %d: exiting", exit_flag);
1084
1038
        return EXIT_SUCCESS;
1085
1039
}
 
1040