-/* apcupsd.c: conky module for APC UPS daemon monitoring
+/* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
+ * vim: ts=4 sw=4 noet ai cindent syntax=c
+ *
+ * apcupsd.c: conky module for APC UPS daemon monitoring
*
* Copyright (C) 2009 Jaromir Smrcek <jaromir.smrcek@zoner.com>
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
- * USA. */
+ * USA.
+ *
+ */
#include "conky.h"
#include "apcupsd.h"
//
// Conky update function for apcupsd data
//
-void update_apcupsd(void) {
+int update_apcupsd(void) {
int i;
APCUPSD_S apc;
memcpy(apc.items[i], "N/A", 4); // including \0
do {
- struct hostent* he = 0;
- struct sockaddr_in addr;
+ struct addrinfo hints;
+ struct addrinfo *ai, *rp;
+ int res;
short sz = 0;
-#ifdef HAVE_GETHOSTBYNAME_R
- struct hostent he_mem;
- int he_errno;
- char hostbuff[2048];
-#endif
+ char portbuf[8];
//
// connect to apcupsd daemon
//
- sock = socket(AF_INET, SOCK_STREAM, 0);
- if (sock < 0) {
- perror("socket");
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = 0;
+ hints.ai_protocol = 0;
+ snprintf(portbuf, 8, "%d", info.apcupsd.port);
+ res = getaddrinfo(info.apcupsd.host, portbuf, &hints, &ai);
+ if (res != 0) {
+ NORM_ERR("APCUPSD getaddrinfo: %s", gai_strerror(res));
break;
}
-#ifdef HAVE_GETHOSTBYNAME_R
- if (gethostbyname_r(info.apcupsd.host, &he_mem, hostbuff, sizeof(hostbuff), &he, &he_errno)) {
- ERR("APCUPSD gethostbyname_r: %s", hstrerror(h_errno));
- break;
+ for (rp = ai; rp != NULL; rp = rp->ai_next) {
+ sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+ if (sock == -1) {
+ continue;
+ }
+ if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
+ break;
+ }
+ close(sock);
}
-#else /* HAVE_GETHOSTBYNAME_R */
- he = gethostbyname(info.apcupsd.host);
- if (!he) {
- herror("gethostbyname");
- break;
- }
-#endif /* HAVE_GETHOSTBYNAME_R */
-
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = info.apcupsd.port;
- memcpy(&addr.sin_addr, he->h_addr, he->h_length);
- if (connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr)) < 0) {
+ freeaddrinfo(ai);
+ if (rp == NULL) {
// no error reporting, the daemon is probably not running
break;
}
-
+
//
// send status request - "status" - 6B
//
// "atomically" copy the data into working set
//
memcpy(info.apcupsd.items, apc.items, sizeof(info.apcupsd.items));
- return;
-}
-
-//
-// fills in the N/A strings and default host:port
-//
-void init_apcupsd(void) {
-
- int i;
- for (i = 0; i < _APCUPSD_COUNT; ++i)
- memcpy(info.apcupsd.items[i], "N/A", 4); // including \0
- memcpy(info.apcupsd.host, "localhost", 10);
- info.apcupsd.port = htons(3551);
+ return 0;
}