Add missing header.
[monky] / src / hddtemp.c
1 #include "conky.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <netdb.h>
8 #include <sys/select.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11
12 #define BUFLEN 512
13 #define PORT 7634
14
15 char buf[BUFLEN];
16
17 int scan_hddtemp(const char *arg, char **dev, char **addr, int *port)
18 {
19         char buf1[32], buf2[64];
20         int n, ret;
21         
22         ret = sscanf(arg, "%31s %63s %d", buf1, buf2, &n);
23         
24         if (ret < 1)
25                 return -1;
26
27         *dev = strdup(buf1);
28         if (ret >= 2)
29                 *addr = strdup(buf2);
30         else
31                 *addr = strdup("127.0.0.1");
32
33         if (ret == 3) 
34                 *port = n;
35         else
36                 *port = PORT;
37
38         return 0;
39 }
40
41 char *get_hddtemp_info(char *dev, char *hostaddr, int port, char *unit)
42 {
43         int sockfd = 0;
44         struct hostent *he;
45         struct sockaddr_in addr;
46         struct timeval tv;
47         fd_set rfds;
48         int len, i, devlen = strlen(dev);
49         char sep;
50         char *p, *out, *r = NULL;
51         
52         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
53                 perror("socket");
54                 return NULL;
55         }
56
57         he = gethostbyname(hostaddr);
58         if (!he) {
59                 perror("gethostbyname");
60                 goto out;
61         }
62
63         addr.sin_family = AF_INET;
64         addr.sin_port = htons(port);
65         addr.sin_addr = *((struct in_addr *)he->h_addr);
66         memset(&(addr.sin_zero), 0, 8);
67
68         if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
69                 perror("connect");
70                 goto out;
71         }
72
73         FD_ZERO(&rfds);
74         FD_SET(sockfd, &rfds);
75
76         /* We're going to wait up to a quarter a second to see whether
77          * there's any data available. Polling with timeout set to 0
78          * doesn't seem to work with hddtemp. */
79         tv.tv_sec = 0;
80         tv.tv_usec = 250000;
81         
82         i = select(sockfd+1, &rfds, NULL, NULL, &tv);
83         if (i == -1)
84                 perror("select");
85
86         /* No data available */
87         if (i <= 0)
88                 goto out;
89         
90         p = buf;
91         len = 0;
92         do {
93                 i = recv(sockfd, p, BUFLEN - (p-buf), 0);
94                 if (i < 0) {
95                         perror("recv");
96                         goto out;
97                 }
98                 len += i;
99                 p += i;
100         } while (i > 0 && p < buf + BUFLEN - 1);
101         
102         if (len < 2) {
103                 goto out;
104         }
105         
106         buf[len] = 0;
107                 
108         /* The first character read is the separator. */
109         sep = buf[0];
110         p = buf+1;
111         
112         while (*p) {
113                 if (!strncmp(p, dev, devlen)) {
114                         p += devlen + 1; 
115                         p = strchr(p, sep);
116                         if (!p) 
117                                 goto out;
118                         p++;
119                         out = p;        
120                         p = strchr(p, sep);
121                         if (!p) 
122                                 goto out;
123                         *p = '\0';
124                         p++;
125                         *unit = *p;     
126                         if (!strncmp(out, "NA", 2)) {
127                                 strcpy(buf, "N/A");
128                                 r = buf;
129                         } else {                                        
130                                 r = out;
131                         }
132                         goto out;
133                 } else {
134                         for (i = 0; i < 5; i++) {
135                                 p = strchr(p, sep);
136                                 if (!p)
137                                         goto out;
138                                 p++;
139                         }
140                 }
141         }
142 out:    close(sockfd);
143         return r;
144 }
145