X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fhddtemp.c;h=3e66a29777bc86e41ae124395d8c1f084bacc1ef;hb=d744f9bfbb192067187d928eeec0d61f7a78e528;hp=66c9f15c657debf9aa72ddd5fb943f17bc17fe3e;hpb=de4f298f3c409b2987fc96bace7d0f21761f0236;p=monky diff --git a/src/hddtemp.c b/src/hddtemp.c index 66c9f15..3e66a29 100644 --- a/src/hddtemp.c +++ b/src/hddtemp.c @@ -1,8 +1,33 @@ +/* Conky, a system monitor, based on torsmo + * + * Any original torsmo code is licensed under the BSD license + * + * All code written since the fork of torsmo is licensed under the GPL + * + * Please see COPYING for details + * + * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen + * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al. + * (see AUTHORS) + * All rights reserved. + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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, see . + * + */ + #include "conky.h" +#include "logging.h" #include -#include -#include -#include #include #include #include @@ -19,133 +44,165 @@ 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 (ret < 1) - return -1; - - *dev = strdup(buf1); - if (ret >= 2) - *addr = strdup(buf2); - else - *addr = strdup("127.0.0.1"); - - if (ret == 3) + + if (!arg) + 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); + strncpy(buf1, "/dev/", 5); + } + *dev = strndup(buf1, text_buffer_size); + + if (ret >= 2) { + *addr = strndup(buf2, text_buffer_size); + } else { + *addr = strndup("127.0.0.1", text_buffer_size); + } + + if (ret == 3) { *port = n; - else + } else { *port = PORT; + } 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 "" 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 or NULL on error or N/A */ +char *get_hddtemp_info(char *dev, char *hostaddr, int port) { int sockfd = 0; - struct hostent *he; + struct hostent he, *he_res = 0; + int he_errno; + char hostbuff[2048]; 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; } - he = gethostbyname(hostaddr); - if (!he) { - perror("gethostbyname"); - goto out; +#ifdef HAVE_GETHOSTBYNAME_R + if (gethostbyname_r(hostaddr, &he, hostbuff, + sizeof(hostbuff), &he_res, &he_errno)) { + ERR("hddtemp gethostbyname_r: %s", hstrerror(h_errno)); +#else /* HAVE_GETHOSTBYNAME_R */ + 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->h_addr); + 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) { + if (connect(sockfd, (struct sockaddr *) &addr, + sizeof(struct sockaddr)) == -1) { perror("connect"); - goto out; + goto GET_OUT; } FD_ZERO(&rfds); FD_SET(sockfd, &rfds); - /* We're going to wait up to a quarter a second to see whether - * there's any data available. Polling with timeout set to 0 - * doesn't seem to work with hddtemp. */ + /* 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 = 250000; - - i = select(sockfd+1, &rfds, NULL, NULL, &tv); - if (i == -1) - { - if (errno == EINTR) /* silently ignore interrupted system call */ - goto out; - else - perror("select"); + 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; } - /* No data available */ - if (i <= 0) - goto out; - p = buf; len = 0; do { - i = recv(sockfd, p, BUFLEN - (p-buf), 0); + i = recv(sockfd, p, BUFLEN - (p - buf), 0); if (i < 0) { perror("recv"); - goto out; + break; } len += i; p += i; } while (i > 0 && p < buf + BUFLEN - 1); - + if (len < 2) { - goto out; + ERR("hddtemp returned nada"); + goto GET_OUT; } - + buf[len] = 0; - - /* 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) - goto out; - p++; - out = p; - p = strchr(p, sep); - if (!p) - goto out; - *p = '\0'; - p++; - *unit = *p; - if (!strncmp(out, "NA", 2)) { - strcpy(buf, "N/A"); - r = buf; - } else { - r = out; - } - goto out; - } else { - for (i = 0; i < 5; i++) { - p = strchr(p, sep); - if (!p) - goto out; - p++; - } - } - } -out: close(sockfd); + + 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); + +GET_OUT: + close(sockfd); return r; } -