diff options
author | michael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2008-12-23 15:46:23 +0000 |
---|---|---|
committer | michael <michael@3ae390bd-cb1e-0410-b409-cd5a39f66f1f> | 2008-12-23 15:46:23 +0000 |
commit | 91348c5ecee2d7b22b2cb8d0af5a41d309efab91 (patch) | |
tree | 65f21f90e24bced996e37b61c0f0e0d08d6fd8f7 | |
parent | c881473ad3e54d4f9c149358173b52b3405262c7 (diff) | |
download | lcd4linux-91348c5ecee2d7b22b2cb8d0af5a41d309efab91.tar.gz |
hddtemp plugin from Scott Bronson
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@907 3ae390bd-cb1e-0410-b409-cd5a39f66f1f
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 12 | ||||
-rw-r--r-- | plugin.c | 5 | ||||
-rw-r--r-- | plugin_hddtemp.c | 312 | ||||
-rw-r--r-- | plugins.m4 | 8 |
7 files changed, 343 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index e38c82c..2c32ce3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -121,6 +121,7 @@ plugin_exec.c \ plugin_fifo.c \ plugin_file.c \ plugin_gps.c \ +plugin_hddtemp.c \ plugin_i2c_sensors.c \ plugin_iconv.c \ plugin_imon.c \ diff --git a/Makefile.in b/Makefile.in index 7c147c4..658cae0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -320,6 +320,7 @@ plugin_exec.c \ plugin_fifo.c \ plugin_file.c \ plugin_gps.c \ +plugin_hddtemp.c \ plugin_i2c_sensors.c \ plugin_iconv.c \ plugin_imon.c \ @@ -512,6 +513,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_fifo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_gps.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_hddtemp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_i2c_sensors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_iconv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_imon.Po@am__quote@ diff --git a/config.h.in b/config.h.in index ee5a8d2..67a52a3 100644 --- a/config.h.in +++ b/config.h.in @@ -305,6 +305,9 @@ /* gps plugin */ #undef PLUGIN_GPS +/* hddtemp plugin */ +#undef PLUGIN_HDDTEMP + /* i2c sensors plugin */ #undef PLUGIN_I2C_SENSORS @@ -8565,6 +8565,7 @@ echo "$as_me: error: run ./configure --with-plugins=..." >&2;} PLUGIN_FIFO="yes" PLUGIN_FILE="yes" PLUGIN_GPS="yes" + PLUGIN_HDDTEMP="yes" PLUGIN_I2C_SENSORS="yes" PLUGIN_ICONV="yes" PLUGIN_IMON="yes" @@ -8617,6 +8618,9 @@ echo "$as_me: error: run ./configure --with-plugins=..." >&2;} gps) PLUGIN_GPS=$val ;; + hddtemp) + PLUGIN_HDDTEMP=$hddtemp + ;; i2c_sensors) PLUGIN_I2C_SENSORS=$val ;; @@ -9148,6 +9152,14 @@ echo "$as_me: WARNING: libnmeap lib not found: gps plugin disabled" >&2;} echo "$as_me: WARNING: nmeap.h header not found: gps plugin disabled" >&2;} fi fi +if test "$PLUGIN_HDDTEMP" = "yes"; then + PLUGINS="$PLUGINS plugin_hddtemp.o" + +cat >>confdefs.h <<\_ACEOF +#define PLUGIN_HDDTEMP 1 +_ACEOF + +fi if test "$PLUGIN_I2C_SENSORS" = "yes"; then PLUGINS="$PLUGINS plugin_i2c_sensors.o" @@ -74,6 +74,8 @@ int plugin_init_file(void); void plugin_exit_file(void); int plugin_init_gps(void); void plugin_exit_gps(void); +int plugin_init_hddtemp(void); +void plugin_exit_hddtemp(void); int plugin_init_i2c_sensors(void); void plugin_exit_i2c_sensors(void); int plugin_init_imon(void); @@ -155,6 +157,9 @@ int plugin_init(void) #ifdef PLUGIN_GPS plugin_init_gps(); #endif +#ifdef PLUGIN_HDDTEMP + plugin_init_hddtemp(); +#endif #ifdef PLUGIN_I2C_SENSORS plugin_init_i2c_sensors(); #endif diff --git a/plugin_hddtemp.c b/plugin_hddtemp.c new file mode 100644 index 0000000..c8d742b --- /dev/null +++ b/plugin_hddtemp.c @@ -0,0 +1,312 @@ +/* $Id$ + * $URL$ + * + * plugin hddtemp + * + * Copyright (C) 2007 Scott Bronson <brons_lcd4linux@rinspin.com> + * Copyright (C) 2004, 2005, 2006, 2007, 2008 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net> + * + * This file is part of LCD4Linux. + * + * LCD4Linux is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * LCD4Linux is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* Example: + * (I tried to put this info on the wiki but Akismet claimed it was spam) + + Widget SmallHDDTemp { + class 'Text' + expression hddtemp('/dev/hda') + width 4 + precision 1 + align 'R' + update tick + } + + hddtemp home page: http://www.guzu.net/linux/hddtemp.php + + Quick Examples: + * hddtemp() -- return temperature of first drive (order is defined by the hddtemp daemon). + * hddtemp('/dev/hda') -- return temperature of /dev/hda on localhost. + * hddtemp('ST3400832A') -- return temperature of the drive with the given ID. + * hddtemp('burly', '') -- return temperature of the first drive on host burly. + * hddtemp('burly', 17634, '/dev/hda') -- return temperature of /dev/hda on burly connecting to the hddtemp daemon listening on port 17634. + +You can find out what drives are being monitored by running + telnet HOST PORT + +i.e. + + $ telnet localhost 7634 + Trying 127.0.0.1... + Connected to localhost. + Escape character is '^]'. + |/dev/hda|ST3400832A|53|C|Connection closed by foreign host. + +This tells me that /dev/hda is a Seagate ST3400832A running at an awfully +toasty 53 degC. + + */ + + +/* + * exported functions: + * + * int plugin_init_hddtemp (void) + * adds various functions + * void plugin_exit_hddtemp (void) + * + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +/* network specific includes */ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <arpa/inet.h> + +/* these should always be included */ +#include "debug.h" +#include "plugin.h" +#include "cfg.h" +#include "thread.h" + + +static int socket_open(const char *name, int port) +{ + struct sockaddr_in server; + struct hostent *host_info; + unsigned long addr; + int sock; + + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + error("[hddtemp] failed to create socket: %s", strerror(errno)); + return -1; + } + + memset(&server, 0, sizeof(server)); + if ((addr = inet_addr(name)) != INADDR_NONE) { + memcpy((char *) &server.sin_addr, &addr, sizeof(addr)); + } else { + host_info = gethostbyname(name); + if (NULL == host_info) { + error("[hddtemp] Unknown server: %s", name); + return -1; + } + memcpy((char *) &server.sin_addr, host_info->h_addr, host_info->h_length); + } + + server.sin_family = AF_INET; + server.sin_port = htons(port); + + if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { + error("[hddtemp] can't connect to server %s: %s", name, strerror(errno)); + return -1; + } + + return sock; +} + + +// replaces all null chars in a buffer with a given character. +static void replace_nulls(char *buf, size_t len, char repl) +{ + char *end = buf + len; + + while (buf < end) { + if (*buf == '\0') { + *buf = repl; + } + + buf += 1; + } +} + + +static size_t hddtemp_read(int socket, char *buf, size_t bufsiz) +{ + size_t count = 0; + ssize_t len; + + while (count < bufsiz) { + len = read(socket, buf + count, bufsiz - count); + if (len > 0) { + replace_nulls(buf + count, len, '@'); + count += len; + } else if (len < 0) { + // an error! + error("[hddtemp] Couldn't read: %s", strerror(errno)); + return -1; + } else { + // remote socket has closed + break; + } + } + + // null-terminate the string + if (count < bufsiz) { + buf[count] = '\0'; + } else { + buf[bufsiz - 1] = '\0'; + } + + return count; +} + + +static int hddtemp_connect(const char *host, int port, char *buf, size_t bufsiz) +{ + int sock, ret; + + sock = socket_open(host, port); + if (sock < 0) { + error("[hddtemp] Error accessing %s:%d: %s", host, port, strerror(errno)); + return -1; + } + + ret = hddtemp_read(sock, buf, bufsiz); + close(sock); + + return ret; +} + + +static char *hddtemp_fetch(char *buf, size_t bufsiz, const char *host, int port, const char *arg) +{ + char *line, *end; + + // fetch a buffer of all hddtemps + if (!hddtemp_connect(host, port, buf, bufsiz)) { + return "err"; + } + // find the line containing the user's specification + line = strstr(buf, arg); + if (!line) { + return "--"; + } + // back up to the beginning of the line + while (line > buf && line[-1] != '\n') { + line--; + } + + // quick sanity check -- each line begins with the separator + if (*line != '|') { + return "fmt1"; + } + // |device|identifier|temp|units| + // skip 3 bars to find the start of the temperature + line = strchr(line + 1, '|'); + if (line && line[0]) + line = strchr(line + 1, '|'); + if (!line || !line[0]) { + return "fmt2"; + } + // set the next bar to '\0' to null-terminate temp + line += 1; + end = strchr(line, '|'); + if (!end) { + return "fmt3"; + } + *end = '\0'; + + return line; +} + + +#ifndef TEST + +static void hddtemp_call(RESULT * result, int argc, RESULT * argv[]) +{ + char buf[4096]; + const char *search = ""; + const char *host = "localhost"; + int port = 7634; + char *out; + + switch (argc) { + case 0: + break; + case 1: + search = R2S(argv[0]); + break; + case 2: + host = R2S(argv[0]); + search = R2S(argv[1]); + default: + if (argv > 3) { + error("hddtemp(): too many parameters"); + } + host = R2S(argv[0]); + port = (int) R2N(argv[1]); + search = R2S(argv[2]); + } + + out = hddtemp_fetch(buf, sizeof(buf), host, port, search); + SetResult(&result, R_STRING, out); +} + + +int plugin_init_hddtemp(void) +{ + info("Adding hddtemp functions!"); + + AddFunction("hddtemp", -1, hddtemp_call); + + return 0; +} + + +void plugin_exit_hddtemp(void) +{ +} +#endif + + + +#ifdef TEST +// Add this to your makefile to make the test_hddtemp app: +// test_hddtemp: plugin_hddtemp.c +// gcc -Wall -Werror -g -DTEST plugin_hddtemp.c -o $@ + +#include <stdarg.h> + +void message(const int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vprintf(format, ap); + putchar('\n'); + va_end(ap); +} + +int main(int argc, char **argv) +{ + char buf[4096]; + char *out = hddtemp_fetch(buf, sizeof(buf), argv[1] ? argv[1] : "/dev/hda"); + printf("OUTPUT: %s\n", out); + return 0; +} +#endif @@ -63,6 +63,7 @@ for plugin in $plugins; do PLUGIN_FIFO="yes" PLUGIN_FILE="yes" PLUGIN_GPS="yes" + PLUGIN_HDDTEMP="yes" PLUGIN_I2C_SENSORS="yes" PLUGIN_ICONV="yes" PLUGIN_IMON="yes" @@ -115,6 +116,9 @@ for plugin in $plugins; do gps) PLUGIN_GPS=$val ;; + hddtemp) + PLUGIN_HDDTEMP=$hddtemp + ;; i2c_sensors) PLUGIN_I2C_SENSORS=$val ;; @@ -242,6 +246,10 @@ if test "$PLUGIN_GPS" = "yes"; then AC_MSG_WARN(nmeap.h header not found: gps plugin disabled) fi fi +if test "$PLUGIN_HDDTEMP" = "yes"; then + PLUGINS="$PLUGINS plugin_hddtemp.o" + AC_DEFINE(PLUGIN_HDDTEMP,1,[hddtemp plugin]) +fi if test "$PLUGIN_I2C_SENSORS" = "yes"; then PLUGINS="$PLUGINS plugin_i2c_sensors.o" AC_DEFINE(PLUGIN_I2C_SENSORS,1,[i2c sensors plugin]) |