1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2025-01-13 19:22:58 +00:00

rewrite hddtemp

This commit is contained in:
Phil Sutter 2008-12-08 16:01:15 +01:00
parent a92601f069
commit bb079848b1
3 changed files with 136 additions and 137 deletions

View File

@ -1513,7 +1513,6 @@ struct text_object {
char *dev;
double update_time;
char *temp;
char unit;
} hddtemp; /* 2 */
#endif
#ifdef EVE
@ -2446,7 +2445,8 @@ static void free_text_objects(struct text_object_list *text_object_list, char fu
case OBJ_hddtemp:
free(obj->data.hddtemp.dev);
free(obj->data.hddtemp.addr);
free(obj->data.hddtemp.temp);
if (obj->data.hddtemp.temp)
free(obj->data.hddtemp.temp);
break;
#endif
case OBJ_entropy_avail:
@ -4090,14 +4090,14 @@ static struct text_object *construct_text_object(const char *s,
#endif
#ifdef HDDTEMP
END OBJ(hddtemp, 0)
if (!arg || scan_hddtemp(arg, &obj->data.hddtemp.dev,
&obj->data.hddtemp.addr, &obj->data.hddtemp.port, &obj->data.hddtemp.temp)) {
if (scan_hddtemp(arg, &obj->data.hddtemp.dev,
&obj->data.hddtemp.addr, &obj->data.hddtemp.port)) {
ERR("hddtemp needs arguments");
obj->type = OBJ_text;
obj->data.s = strndup("${hddtemp}", text_buffer_size);
obj->data.hddtemp.update_time = 0;
return NULL;
}
} else
obj->data.hddtemp.temp = NULL;
#endif
#ifdef TCP_PORT_MONITOR
END OBJ(tcp_portmon, INFO_TCP_PORT_MONITOR)
@ -5625,28 +5625,29 @@ static void generate_text_internal(char *p, int p_max_size,
#endif
#ifdef HDDTEMP
OBJ(hddtemp) {
char *endptr, unit;
long val;
if (obj->data.hddtemp.update_time < current_update_time - 30) {
char *str = get_hddtemp_info(obj->data.hddtemp.dev,
obj->data.hddtemp.addr, obj->data.hddtemp.port/*, &obj->data.hddtemp.unit*/);
if (str) {
strncpy(obj->data.hddtemp.temp, str, text_buffer_size);
} else {
obj->data.hddtemp.temp[0] = 0;
}
if (obj->data.hddtemp.temp)
free(obj->data.hddtemp.temp);
obj->data.hddtemp.temp = get_hddtemp_info(obj->data.hddtemp.dev,
obj->data.hddtemp.addr, obj->data.hddtemp.port);
obj->data.hddtemp.update_time = current_update_time;
}
if (!obj->data.hddtemp.temp) {
snprintf(p, p_max_size, "N/A");
} else {
char *endptr;
int val = (int)strtol(obj->data.hddtemp.temp, &endptr, 10);
/* FIXME: review this, it looks broken */
if (*endptr != '\0' || obj->data.hddtemp.unit == '*')
snprintf(p, p_max_size, "%s", obj->data.hddtemp.temp);
val = strtol(obj->data.hddtemp.temp + 1, &endptr, 10);
unit = obj->data.hddtemp.temp[0];
if (*endptr != '\0')
snprintf(p, p_max_size, "N/A");
else if (unit == 'C')
temp_print(p, p_max_size, (double)val, TEMP_CELSIUS);
else if (unit == 'F')
temp_print(p, p_max_size, (double)val, TEMP_FAHRENHEIT);
else
temp_print(p, p_max_size, (double)val,
((obj->data.hddtemp.unit == 'C') ?
TEMP_CELSIUS : TEMP_FAHRENHEIT));
snprintf(p, p_max_size, "N/A");
}
}
#endif

View File

@ -39,16 +39,16 @@
char buf[BUFLEN];
int scan_hddtemp(const char *arg, char **dev, char **addr, int *port, char** temp)
int scan_hddtemp(const char *arg, char **dev, char **addr, int *port)
{
char buf1[32], buf2[64];
int n, ret;
ret = sscanf(arg, "%31s %63s %d", buf1, buf2, &n);
if (!arg)
return 1;
if (ret < 1) {
return -1;
}
if ((ret = sscanf(arg, "%31s %63s %d", buf1, buf2, &n)) < 1)
return 1;
if (strncmp(buf1, "/dev/", 5)) {
strncpy(buf1 + 5, buf1, 32 - 5);
@ -68,13 +68,51 @@ int scan_hddtemp(const char *arg, char **dev, char **addr, int *port, char** tem
*port = PORT;
}
*temp = malloc(text_buffer_size);
memset(*temp, 0, text_buffer_size);
return 0;
}
char *get_hddtemp_info(char *dev, char *hostaddr, int port/*, char *unit*/)
/* this is an iterator:
* set line to NULL in consecutive calls to get the next field
* returns "<dev><unit><val>" or NULL on error
*/
static char *read_hdd_val(const char *line)
{
static char line_s[512] = "\0";
static char *p = 0;
char *dev, *val, unit;
char *ret = NULL;
if (line) {
snprintf(line_s, 512, "%s", line);
p = line_s;
}
if (!(*line_s))
return ret;
/* read the device */
dev = ++p;
if (!(p = strchr(p, line_s[0])))
return ret;
*(p++) = '\0';
/* jump over the devname */
if (!(p = strchr(p, line_s[0])))
return ret;
/* read the value */
val = ++p;
if (!(p = strchr(p, line_s[0])))
return ret;
*(p++) = '\0';
unit = *(p++);
/* preset p for next call */
p = strchr(p + 1, line_s[0]);
if (dev && *dev && val && *val) {
asprintf(&ret, "%s%c%s", dev, unit, val);
}
return ret;
}
/* returns <unit><val> or NULL on error or N/A */
char *get_hddtemp_info(char *dev, char *hostaddr, int port)
{
int sockfd = 0;
struct hostent he, *he_res = 0;
@ -83,127 +121,87 @@ char *get_hddtemp_info(char *dev, char *hostaddr, int port/*, char *unit*/)
struct sockaddr_in addr;
struct timeval tv;
fd_set rfds;
int len, i, devlen = strlen(dev);
char sep;
char *p, *out, *r = NULL;
int len, i;
char *p, *r = NULL;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return NULL;
goto GET_OUT;
}
do {
#ifdef HAVE_GETHOSTBYNAME_R
if (gethostbyname_r(hostaddr, &he, hostbuff, sizeof(hostbuff), &he_res, &he_errno)) { // get the host info
ERR("hddtemp gethostbyname_r: %s", hstrerror(h_errno));
break;
}
if (gethostbyname_r(hostaddr, &he, hostbuff,
sizeof(hostbuff), &he_res, &he_errno)) {
ERR("hddtemp gethostbyname_r: %s", hstrerror(h_errno));
#else /* HAVE_GETHOSTBYNAME_R */
he_res = gethostbyname(hostaddr);
if (!he_res) {
perror("gethostbyname");
break;
}
if (!(he_res = gethostbyname(hostaddr))) {
perror("gethostbyname()");
#endif /* HAVE_GETHOSTBYNAME_R */
goto GET_OUT;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr = *((struct in_addr *) he_res->h_addr);
memset(&(addr.sin_zero), 0, 8);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr = *((struct in_addr *) he_res->h_addr);
memset(&(addr.sin_zero), 0, 8);
if (connect(sockfd, (struct sockaddr *) &addr,
sizeof(struct sockaddr)) == -1) {
perror("connect");
if (connect(sockfd, (struct sockaddr *) &addr,
sizeof(struct sockaddr)) == -1) {
perror("connect");
goto GET_OUT;
}
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
/* We're going to wait up to a half second to see whether there's any
* data available. Polling with timeout set to 0 doesn't seem to work
* with hddtemp.
*/
tv.tv_sec = 0;
tv.tv_usec = 500000;
i = select(sockfd + 1, &rfds, NULL, NULL, &tv);
if (i == -1) { /* select() failed */
if (errno == EINTR) {
/* silently ignore interrupted system call */
goto GET_OUT;
} else {
perror("select");
}
} else if (i == 0) { /* select() timeouted */
ERR("hddtemp had nothing for us");
goto GET_OUT;
}
p = buf;
len = 0;
do {
i = recv(sockfd, p, BUFLEN - (p - buf), 0);
if (i < 0) {
perror("recv");
break;
}
len += i;
p += i;
} while (i > 0 && p < buf + BUFLEN - 1);
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds);
if (len < 2) {
ERR("hddtemp returned nada");
goto GET_OUT;
}
/* We're going to wait up to a half second to see whether there's any
* data available. Polling with timeout set to 0 doesn't seem to work
* with hddtemp.
*/
tv.tv_sec = 0;
tv.tv_usec = 500000;
buf[len] = 0;
i = select(sockfd + 1, &rfds, NULL, NULL, &tv);
if (i == -1) {
if (errno == EINTR) { /* silently ignore interrupted system call */
break;
} else {
perror("select");
}
}
if ((p = read_hdd_val(buf)) == NULL)
goto GET_OUT;
do {
if (!strncmp(dev, p, strlen(dev)))
asprintf(&r, "%s", p + strlen(dev));
free(p);
} while(!r && (p = read_hdd_val(NULL)) != NULL);
/* No data available */
if (i <= 0) {
ERR("hddtemp had nothing for us");
break;
}
p = buf;
len = 0;
do {
i = recv(sockfd, p, BUFLEN - (p - buf), 0);
if (i < 0) {
perror("recv");
break;
}
len += i;
p += i;
} while (i > 0 && p < buf + BUFLEN - 1);
if (len < 2) {
ERR("hddtemp returned nada");
break;
}
buf[len] = 0;
// printf("read: '%s'\n", buf);
/* The first character read is the separator. */
sep = buf[0];
p = buf + 1;
while (*p) {
if (!strncmp(p, dev, devlen)) {
p += devlen + 1;
p = strchr(p, sep);
if (!p) {
break;
}
p++;
out = p;
p = strchr(p, sep);
if (!p) {
break;
}
*p = '\0';
p++;
// *unit = *p;
if (!strncmp(out, "NA", 2)) {
strncpy(buf, "N/A", BUFLEN);
r = buf;
} else {
r = out;
}
break;
} else {
for (i = 0; i < 5; i++) {
p = strchr(p, sep);
if (!p) {
break;
}
p++;
}
if (!p && i < 5) {
break;
}
}
}
} while (0);
GET_OUT:
close(sockfd);
// printf("got: '%s'\n", r);
return r;
}

View File

@ -1,7 +1,7 @@
#ifndef HDDTEMP_H_
#define HDDTEMP_H_
int scan_hddtemp(const char *arg, char **dev, char **addr, int *port, char **temp);
char *get_hddtemp_info(char *dev, char *addr, int port/*, char *unit*/);
int scan_hddtemp(const char *arg, char **dev, char **addr, int *port);
char *get_hddtemp_info(char *dev, char *addr, int port);
#endif /*HDDTEMP_H_*/