xmms/bmp/audacious/infopipe reorgamization
[monky] / src / common.c
1 /*
2  * Conky, a system monitor, based on torsmo
3  *
4  * This program is licensed under BSD license, read COPYING
5  *
6  *  $Id$
7  */
8
9 #include "conky.h"
10 #include "remoted.h"
11 #include "remotec.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <errno.h>
17 #include <sys/time.h>
18
19 struct information info;
20
21 void update_uname()
22 {
23         uname(&info.uname_s);
24 }
25
26 double get_time()
27 {
28         struct timeval tv;
29         gettimeofday(&tv, 0);
30         return tv.tv_sec + (tv.tv_usec / 1000000.0);
31 }
32
33 FILE *open_file(const char *file, int *reported)
34 {
35         FILE *fp = fopen(file, "r");
36         if (!fp) {
37                 if (!reported || *reported == 0) {
38                         ERR("can't open %s: %s", file, strerror(errno));
39                         if (reported)
40                                 *reported = 1;
41                 }
42                 return 0;
43         }
44
45         return fp;
46 }
47
48 void variable_substitute(const char *s, char *dest, unsigned int n)
49 {
50         while (*s && n > 1) {
51                 if (*s == '$') {
52                         s++;
53                         if (*s != '$') {
54                                 char buf[256];
55                                 const char *a, *var;
56                                 unsigned int len;
57
58                                 /* variable is either $foo or ${foo} */
59                                 if (*s == '{') {
60                                         s++;
61                                         a = s;
62                                         while (*s && *s != '}')
63                                                 s++;
64                                 } else {
65                                         a = s;
66                                         while (*s && (isalnum((int) *s)
67                                                       || *s == '_'))
68                                                 s++;
69                                 }
70
71                                 /* copy variable to buffer and look it up */
72                                 len = (s - a > 255) ? 255 : (s - a);
73                                 strncpy(buf, a, len);
74                                 buf[len] = '\0';
75
76                                 if (*s == '}')
77                                         s++;
78
79                                 var = getenv(buf);
80
81                                 if (var) {
82                                         /* add var to dest */
83                                         len = strlen(var);
84                                         if (len >= n)
85                                                 len = n - 1;
86                                         strncpy(dest, var, len);
87                                         dest += len;
88                                         n -= len;
89                                 }
90                                 continue;
91                         }
92                 }
93
94                 *dest++ = *s++;
95                 n--;
96         }
97
98         *dest = '\0';
99 }
100
101 /* network interface stuff */
102
103 static struct net_stat netstats[16];
104
105 struct net_stat *get_net_stat(const char *dev)
106 {
107         unsigned int i;
108
109         if (!dev)
110                 return 0;
111
112         /* find interface stat */
113         for (i = 0; i < 16; i++) {
114                 if (netstats[i].dev && strcmp(netstats[i].dev, dev) == 0)
115                         return &netstats[i];
116         }
117
118         /* wasn't found? add it */
119         if (i == 16) {
120                 for (i = 0; i < 16; i++) {
121                         if (netstats[i].dev == 0) {
122                                 netstats[i].dev = strdup(dev);
123                                 return &netstats[i];
124                         }
125                 }
126         }
127
128         CRIT_ERR("too many interfaces used (limit is 16)");
129         return 0;
130 }
131
132 void format_seconds(char *buf, unsigned int n, long t)
133 {
134         if (t >= 24 * 60 * 60)  /* hours necessary when there are days? */
135                 snprintf(buf, n, "%ldd %ldh %ldm", t / 60 / 60 / 24,
136                          (t / 60 / 60) % 24, (t / 60) % 60);
137         else if (t >= 60 * 60)
138                 snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
139                          (t / 60) % 60);
140         else
141                 snprintf(buf, n, "%ldm %lds", t / 60, t % 60);
142 }
143
144 void format_seconds_short(char *buf, unsigned int n, long t)
145 {
146         if (t >= 24 * 60 * 60)
147                 snprintf(buf, n, "%ldd %ldh", t / 60 / 60 / 24,
148                          (t / 60 / 60) % 24);
149         else if (t >= 60 * 60)
150                 snprintf(buf, n, "%ldh %ldm", (t / 60 / 60) % 24,
151                          (t / 60) % 60);
152         else
153                 snprintf(buf, n, "%ldm", t / 60);
154 }
155
156 static double last_meminfo_update;
157 static double last_fs_update;
158
159 unsigned long long need_mask;
160
161 void update_stuff()
162 {
163         unsigned int i;
164         info.mask = 0;
165
166         if (no_buffers)
167                 need_mask |= 1 << INFO_BUFFERS;
168
169         /* clear speeds and up status in case device was removed and doesn't get
170          * updated */
171
172         for (i = 0; i < 16; i++) {
173                 if (netstats[i].dev) {
174                         netstats[i].up = 0;
175                         netstats[i].recv_speed = 0.0;
176                         netstats[i].trans_speed = 0.0;
177                 }
178         }
179
180         prepare_update();
181         /* client(); this is approximately where the client should be called */
182 #define NEED(a) ((need_mask & (1 << a)) && ((info.mask & (1 << a)) == 0))
183
184         if (NEED(INFO_UPTIME))
185                 update_uptime();
186
187         if (NEED(INFO_PROCS))
188                 update_total_processes();
189
190         if (NEED(INFO_RUN_PROCS))
191                 update_running_processes();
192
193         if (NEED(INFO_CPU))
194                 update_cpu_usage();
195
196         if (NEED(INFO_NET))
197                 update_net_stats();
198
199         if (NEED(INFO_DISKIO))
200                 update_diskio();
201
202         if (NEED(INFO_WIFI))
203                 update_wifi_stats();
204
205         if (NEED(INFO_MAIL))
206                 update_mail_count();
207
208
209
210 #if defined(__linux__)
211         if (NEED(INFO_I8K))
212                 update_i8k();
213 #endif /* __linux__ */
214         
215 #ifdef MLDONKEY
216         if (NEED(INFO_MLDONKEY))
217                 get_mldonkey_status(&mlconfig, &mlinfo);
218 #endif
219
220 #ifdef SETI
221         if (NEED(INFO_SETI))
222                 update_seti();
223 #endif
224
225 #ifdef MPD
226         if (NEED(INFO_MPD))
227                 update_mpd();
228 #endif
229 #if defined(XMMS_H) || defined(BMP_H) || defined(AUDACIOUS_H) || defined(INFOPIPE_H)
230         if (NEED(INFO_XMMS))
231                 update_xmms();
232 #endif
233 #ifdef BMPX
234         if (NEED(INFO_BMPX))
235                 update_bmpx();
236 #endif
237
238         if (NEED(INFO_LOADAVG))
239                 update_load_average();
240
241
242         if ((NEED(INFO_MEM) || NEED(INFO_BUFFERS) || NEED(INFO_TOP)) &&
243             current_update_time - last_meminfo_update > 6.9) {
244                 update_meminfo();
245                 if (no_buffers) {
246                         info.mem -= info.bufmem;
247                 }
248                 last_meminfo_update = current_update_time;
249         }
250
251         if (NEED(INFO_TOP))
252                 update_top();
253
254         /* update_fs_stat() won't do anything if there aren't fs -things */
255         if (NEED(INFO_FS) && current_update_time - last_fs_update > 12.9) {
256                 update_fs_stats();
257                 last_fs_update = current_update_time;
258         }
259 #ifdef TCP_PORT_MONITOR
260         if (NEED(INFO_TCP_PORT_MONITOR))
261                 update_tcp_port_monitor_collection( info.p_tcp_port_monitor_collection );
262 #endif
263 }
264
265 int round_to_int(float f)
266 {
267     int intval = (int)f;
268     double delta = f - intval;
269     if (!(delta < 0.5)) {
270         ++intval;
271     }
272
273     return intval;
274 }