get_battery_* stubs for openbsd.c
[monky] / src / openbsd.c
1 /*
2  * openbsd.c
3  * Contains OpenBSD specific stuff
4  *
5  */
6
7 #include <sys/dkstat.h>
8 #include <sys/param.h>
9 #include <sys/resource.h>
10 #include <sys/socket.h>
11 #include <sys/sysctl.h>
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <sys/vmmeter.h>
15 #include <sys/user.h>
16 #include <sys/ioctl.h>
17 #include <sys/sensors.h>
18 #include <sys/malloc.h>
19 #include <sys/swap.h>
20 #include <kvm.h>
21
22 #include <net/if.h>
23 #include <net/if_media.h>
24 #include <netinet/in.h>
25
26 #include <err.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <ifaddrs.h>
30 #include <limits.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <machine/apmvar.h>
36
37 #include <net80211/ieee80211.h>
38 #include <net80211/ieee80211_ioctl.h>
39
40 #include "conky.h"
41
42 #define MAXSHOWDEVS             16
43
44 #define LOG1024                 10
45 #define pagetok(size) ((size) << pageshift)
46
47 inline void proc_find_top(struct process **cpu, struct process **mem);
48
49 static short cpu_setup = 0;
50 static kvm_t *kd = 0;
51
52 struct ifmibdata *data = NULL;
53 size_t len = 0;
54
55 int init_kvm = 0;
56 int init_sensors = 0;
57
58 static int kvm_init()
59 {
60         if(init_kvm)
61                 return 1;
62
63         kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, NULL);
64         if(kd == NULL)
65                 fprintf(stderr, "error opening kvm\n");
66         else    init_kvm = 1;
67
68         return 1;
69 }
70
71 /* note: swapmode taken from 'top' source */
72 /*
73  * swapmode is rewritten by Tobias Weingartner <weingart@openbsd.org>
74  * to be based on the new swapctl(2) system call.
75  */
76 static int
77 swapmode(int *used, int *total)
78 {
79         struct swapent *swdev;
80         int nswap, rnswap, i;
81
82         nswap = swapctl(SWAP_NSWAP, 0, 0);
83         if (nswap == 0)
84                 return 0;
85
86         swdev = malloc(nswap * sizeof(*swdev));
87         if (swdev == NULL)
88                 return 0;
89
90         rnswap = swapctl(SWAP_STATS, swdev, nswap);
91         if (rnswap == -1)
92                 return 0;
93
94         /* if rnswap != nswap, then what? */
95
96         /* Total things up */
97         *total = *used = 0;
98         for (i = 0; i < nswap; i++) {
99                 if (swdev[i].se_flags & SWF_ENABLE) {
100                         *used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
101                         *total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
102                 }
103         }
104         free(swdev);
105         return 1;
106 }
107
108 void
109 update_uptime()
110 {
111         int mib[2] = { CTL_KERN, KERN_BOOTTIME };
112         struct timeval boottime;
113         time_t now;
114         size_t size = sizeof (boottime);
115
116         if ((sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) &&
117                         (boottime.tv_sec != 0)) {
118                 time(&now);
119                 info.uptime = now - boottime.tv_sec;
120         } else {
121                 fprintf(stderr, "Could not get uptime\n");
122                 info.uptime = 0;
123         }
124 }
125
126 void
127 update_meminfo()
128 {
129         static int mib[2] = {CTL_VM, VM_METER};
130         struct vmtotal vmtotal;
131         size_t size;
132         int pagesize, pageshift, swap_avail, swap_used;
133
134         pagesize = getpagesize();
135         pageshift = 0;
136         while (pagesize > 1) {
137                 pageshift++;
138                 pagesize >>= 1;
139         }
140
141         /* we only need the amount of log(2)1024 for our conversion */
142         pageshift -= LOG1024;
143
144         /* get total -- systemwide main memory usage structure */
145         size = sizeof(vmtotal);
146         if (sysctl(mib, 2, &vmtotal, &size, NULL, 0) < 0) {
147                 warn("sysctl failed");
148                 bzero(&vmtotal, sizeof(vmtotal));
149         }
150
151         info.memmax =  pagetok(vmtotal.t_rm) + pagetok(vmtotal.t_free);
152         info.mem = pagetok(vmtotal.t_rm);
153
154         if ((swapmode(&swap_used, &swap_avail)) >= 0) {
155                 info.swapmax = swap_avail;
156                 info.swap = swap_used;
157         } else {
158                 info.swapmax = 0;
159                 info.swap = 0;
160         }
161 }
162
163 void
164 update_net_stats()
165 {
166         struct net_stat *ns;
167         double delta;
168         long long r, t, last_recv, last_trans;
169         struct ifaddrs *ifap, *ifa;
170         struct if_data *ifd;
171
172
173         /* get delta */
174         delta = current_update_time - last_update_time;
175         if (delta <= 0.0001)
176                 return;
177
178         if (getifaddrs(&ifap) < 0)
179                 return;
180
181         for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
182                 ns = get_net_stat((const char *) ifa->ifa_name);
183
184                 if (ifa->ifa_flags & IFF_UP) {
185                         struct ifaddrs *iftmp;
186
187                         ns->up = 1;
188                         ns->linkstatus = 1;
189                         last_recv = ns->recv;
190                         last_trans = ns->trans;
191
192                         if (ifa->ifa_addr->sa_family != AF_LINK)
193                                 continue;
194
195                         for (iftmp = ifa->ifa_next; iftmp != NULL &&
196                                 strcmp(ifa->ifa_name, iftmp->ifa_name) == 0;
197                                 iftmp = iftmp->ifa_next)
198                                 if (iftmp->ifa_addr->sa_family == AF_INET)
199                                         memcpy(&(ns->addr), iftmp->ifa_addr,
200                                                 iftmp->ifa_addr->sa_len);
201
202                         ifd = (struct if_data *) ifa->ifa_data;
203                         r = ifd->ifi_ibytes;
204                         t = ifd->ifi_obytes;
205
206                         if (r < ns->last_read_recv)
207                                 ns->recv +=
208                                     ((long long) 4294967295U -
209                                         ns->last_read_recv) + r;
210                         else
211                                 ns->recv += (r - ns->last_read_recv);
212
213                         ns->last_read_recv = r;
214
215                         if (t < ns->last_read_trans)
216                                 ns->trans +=
217                                     ((long long) 4294967295U -
218                                         ns->last_read_trans) + t;
219                         else
220                                 ns->trans += (t - ns->last_read_trans);
221
222                         ns->last_read_trans = t;
223
224                         /* calculate speeds */
225                         ns->recv_speed = (ns->recv - last_recv) / delta;
226                         ns->trans_speed = (ns->trans - last_trans) / delta;
227                 } else {
228                         ns->up = 0;
229                         ns->linkstatus = 0;
230                 }
231         }
232
233         freeifaddrs(ifap);
234 }
235
236 void
237 update_total_processes()
238 {
239         int n_processes;
240
241         kvm_init();
242         kvm_getprocs(kd, KERN_PROC_ALL, 0, &n_processes); 
243
244         info.procs = n_processes;
245 }
246
247 void
248 update_running_processes()
249 {
250         struct kinfo_proc2 *p;
251         int n_processes;
252         int i, cnt = 0;
253
254         kvm_init();
255         int max_size = sizeof(struct kinfo_proc2);
256         p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
257         for (i = 0; i < n_processes; i++) {
258                 if (p[i].p_stat == SRUN)
259                         cnt++;
260         }
261
262         info.run_procs = cnt;
263 }
264
265 struct cpu_load_struct {
266         unsigned long load[5];
267 };
268
269 struct cpu_load_struct fresh = { {0, 0, 0, 0, 0} };
270 long cpu_used, oldtotal, oldused;
271
272 void
273 get_cpu_count()
274 {
275         /*
276          * FIXME: is it possible to get per cpu stats with openbsd?
277          */
278 #if 0
279         int cpu_count = 0;
280         int mib[2] = { CTL_HW, HW_NCPU };
281         size_t len = sizeof(cpu_count);
282         if (sysctl(mib, 2, &cpu_count, &len, NULL, 0) == 0)
283                 info.cpu_count = cpu_count;
284         else    /* last resort, 1 cpu */
285 #endif
286                 info.cpu_count = 1;
287
288         info.cpu_usage = malloc(info.cpu_count * sizeof (float));
289         if (info.cpu_usage == NULL)
290                 CRIT_ERR("malloc");
291 }
292
293 void
294 update_cpu_usage()
295 {
296         int mib[2] = { CTL_KERN, KERN_CPTIME };
297         long used, total;
298         long cp_time[CPUSTATES];
299         size_t len = sizeof (cp_time);
300
301         /* add check for !info.cpu_usage since that mem is freed on a SIGUSR1 */
302         if ((cpu_setup == 0) || (!info.cpu_usage)) {
303                 get_cpu_count();
304                 cpu_setup = 1;
305         }
306
307         if (sysctl(mib, 2, &cp_time, &len, NULL, 0) < 0) {
308                 (void) fprintf(stderr, "Cannot get kern.cp_time");
309         }
310
311         fresh.load[0] = cp_time[CP_USER];
312         fresh.load[1] = cp_time[CP_NICE];
313         fresh.load[2] = cp_time[CP_SYS];
314         fresh.load[3] = cp_time[CP_IDLE];
315         fresh.load[4] = cp_time[CP_IDLE];
316
317         used = fresh.load[0] + fresh.load[1] + fresh.load[2];
318         total =
319             fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3];
320
321         if ((total - oldtotal) != 0) {
322                 info.cpu_usage[0] = ((double) (used - oldused)) /
323                         (double) (total - oldtotal);
324         } else {
325                 info.cpu_usage[0] = 0;
326         }
327
328         oldused = used;
329         oldtotal = total;
330 }
331
332 void
333 update_load_average()
334 {
335         double v[3];
336         getloadavg(v, 3);
337
338         info.loadavg[0] = (float) v[0];
339         info.loadavg[1] = (float) v[1];
340         info.loadavg[2] = (float) v[2];
341 }
342
343 /* read sensors from sysctl */
344 void update_obsd_sensors()
345 {
346         int sensor_cnt, dev, numt, mib[5] = { CTL_HW, HW_SENSORS, 0, 0, 0 };
347         struct sensor sensor;
348         struct sensordev sensordev;
349         size_t slen,sdlen;
350         enum sensor_type type;
351
352         slen = sizeof(sensor);
353         sdlen = sizeof(sensordev);
354
355         sensor_cnt = 0;
356
357         dev = obsd_sensors.device; // FIXME: read more than one device
358
359         /* for (dev = 0; dev < MAXSENSORDEVICES; dev++) { */
360                 mib[2] = dev;
361                 if(sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) {
362                         if (errno != ENOENT)
363                                 warn("sysctl");
364                         return;
365                         //continue;
366                 }
367                 for (type = 0; type < SENSOR_MAX_TYPES; type++) {
368                         mib[3] = type;
369                         for (numt = 0; numt < sensordev.maxnumt[type]; numt++) {
370                                 mib[4] = numt;
371                                 if (sysctl(mib, 5, &sensor, &slen, NULL, 0)
372                                     == -1) {
373                                         if (errno != ENOENT)
374                                                 warn("sysctl");
375                                         continue;
376                                 }
377                                 if (sensor.flags & SENSOR_FINVALID)
378                                         continue;
379
380                                 switch (type) {
381                                         case SENSOR_TEMP:
382                                                 //printf("num: %i value: %.2f\n", sensor.numt, (sensor.value - 273150000) / 1000000.0);
383                                                 obsd_sensors.temp[dev][sensor.numt] = (sensor.value - 273150000) / 1000000.0;
384                                                 break;
385                                         case SENSOR_FANRPM:
386                                                 //printf("num: %i value: %i\n", sensor.numt, sensor.value);
387                                                 obsd_sensors.fan[dev][sensor.numt] = sensor.value;
388                                                 break;
389                                         case SENSOR_VOLTS_DC:
390                                                 obsd_sensors.volt[dev][sensor.numt] = sensor.value/1000000.0;
391                                                 break;
392                                         default:
393                                                 break;
394                                 }
395
396                                 sensor_cnt++;
397                         }
398                 }
399         /* } */
400
401         init_sensors = 1;
402 }
403
404 /* chipset vendor */
405 void get_obsd_vendor(char *buf, size_t client_buffer_size)
406 {
407         int mib[2];
408         mib[0] = CTL_HW;
409         mib[1] = HW_VENDOR;
410         char vendor[64];
411         size_t size = sizeof(vendor);
412         if(sysctl(mib, 2, vendor, &size, NULL, 0) == -1) {
413                 fprintf(stderr, "error reading vendor");
414                 snprintf(buf, client_buffer_size, "unknown");
415         } else {
416                 snprintf(buf, client_buffer_size, "%s", vendor);
417         }
418 }
419
420 /* chipset name */
421 void get_obsd_product(char *buf, size_t client_buffer_size)
422 {
423         int mib[2];
424         mib[0] = CTL_HW;
425         mib[1] = HW_PRODUCT;
426         char product[64];
427         size_t size = sizeof(product);
428         if(sysctl(mib, 2, product, &size, NULL, 0) == -1) {
429                 fprintf(stderr, "error reading product");
430                 snprintf(buf, client_buffer_size, "unknown");
431         } else {
432                 snprintf(buf, client_buffer_size, "%s", product);
433         }
434 }
435
436 /* rdtsc() and get_freq_dynamic() copied from linux.c */
437
438 #if  defined(__i386) || defined(__x86_64)
439 __inline__ unsigned long long int
440 rdtsc()
441 {
442         unsigned long long int x;
443         __asm__ volatile(".byte 0x0f, 0x31":"=A" (x));
444         return (x);
445 }
446 #endif
447
448 /* return system frequency in MHz (use divisor=1) or GHz (use divisor=1000) */
449 void
450 get_freq_dynamic(char *p_client_buffer, size_t client_buffer_size,
451                 char *p_format, int divisor)
452 {
453 #if  defined(__i386) || defined(__x86_64) 
454         struct timezone tz;
455         struct timeval tvstart, tvstop;
456         unsigned long long cycles[2];   /* gotta be 64 bit */
457         unsigned int microseconds;      /* total time taken */
458
459         memset(&tz, 0, sizeof (tz));
460
461         /* get this function in cached memory */
462         gettimeofday(&tvstart, &tz);
463         cycles[0] = rdtsc();
464         gettimeofday(&tvstart, &tz);
465
466         /* we don't trust that this is any specific length of time */
467         usleep(100);
468         cycles[1] = rdtsc();
469         gettimeofday(&tvstop, &tz);
470         microseconds = ((tvstop.tv_sec - tvstart.tv_sec) * 1000000) +
471                 (tvstop.tv_usec - tvstart.tv_usec);
472
473         snprintf(p_client_buffer, client_buffer_size, p_format,
474                 (float)((cycles[1] - cycles[0]) / microseconds) / divisor);
475 #else
476         get_freq(p_client_buffer, client_buffer_size, p_format, divisor);
477 #endif
478 }
479
480 /*void*/
481 char
482 get_freq(char *p_client_buffer, size_t client_buffer_size,
483                 char *p_format, int divisor, unsigned int cpu)
484 {
485         int freq = cpu;
486         int mib[2] = { CTL_HW, HW_CPUSPEED };
487         
488         if (!p_client_buffer || client_buffer_size <= 0 ||
489                         !p_format || divisor <= 0)
490                 return 0;
491
492         size_t size = sizeof(freq);
493         if(sysctl(mib, 2, &freq, &size, NULL, 0) == 0)
494                 snprintf(p_client_buffer, client_buffer_size,
495                                 p_format, (float)freq/divisor);
496         else
497                 snprintf(p_client_buffer, client_buffer_size, p_format, 0.0f);
498
499         return 1;
500 }
501
502 void
503 update_top()
504 {
505         proc_find_top(info.cpu, info.memu);
506 }
507
508 void
509 update_wifi_stats()
510 {
511         struct net_stat * ns;
512         struct ifaddrs *ifap, *ifa;
513         struct ifmediareq ifmr;
514         struct ieee80211_nodereq nr;
515         struct ieee80211_bssid bssid;
516         int s,ibssid;
517
518         /*
519          * Get iface table
520          */
521         if (getifaddrs(&ifap) < 0)
522                 return;
523
524         for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
525                 ns = get_net_stat((const char *) ifa->ifa_name);
526
527                 s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
528
529                 /* Get media type */
530                 bzero(&ifmr, sizeof(ifmr));
531                 strlcpy(ifmr.ifm_name, ifa->ifa_name, IFNAMSIZ);
532                 if (ioctl(s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0)
533                         goto cleanup;
534                 
535                 /*
536                  * We can monitor only wireless interfaces
537                  * which not in hostap mode
538                  */
539                 if ((ifmr.ifm_active & IFM_IEEE80211) &&
540                                 !(ifmr.ifm_active & IFM_IEEE80211_HOSTAP)) {
541                         /* Get wi status */
542
543                         memset(&bssid, 0, sizeof(bssid));
544                         strlcpy(bssid.i_name, ifa->ifa_name, sizeof(bssid.i_name));
545                         ibssid = ioctl(s, SIOCG80211BSSID, &bssid);
546
547                         bzero(&nr, sizeof(nr));
548                         bcopy(bssid.i_bssid, &nr.nr_macaddr, sizeof(nr.nr_macaddr));
549                         strlcpy(nr.nr_ifname, ifa->ifa_name, sizeof(nr.nr_ifname));
550
551                         if (ioctl(s, SIOCG80211NODE, &nr) == 0 && nr.nr_rssi) {
552                                 //if (nr.nr_max_rssi)
553                                 //      printf(" %u%%", IEEE80211_NODEREQ_RSSI(&nr));
554                                 //else 
555                                         ns->linkstatus = nr.nr_rssi;
556                         }
557                 }
558 cleanup:
559                 close(s);
560         }
561 }
562 void
563 update_diskio()
564 {
565         return; /* XXX implement? hifi: not sure how */
566 }
567
568 /*
569  * While topless is obviously better, top is also not bad.
570  */
571
572 int
573 comparecpu(const void *a, const void *b)
574 {
575         if (((struct process *)a)->amount > ((struct process *)b)->amount)
576                 return (-1);
577
578         if (((struct process *)a)->amount < ((struct process *)b)->amount)
579                 return (1);
580
581         return (0);
582 }
583
584 int
585 comparemem(const void *a, const void *b)
586 {
587         if (((struct process *)a)->totalmem > ((struct process *)b)->totalmem)
588                 return (-1);
589
590         if (((struct process *)a)->totalmem < ((struct process *)b)->totalmem)
591                 return (1);
592
593         return (0);
594 }
595
596 inline void
597 proc_find_top(struct process **cpu, struct process **mem)
598 {
599         struct kinfo_proc2 *p;
600         int n_processes;
601         int i, j = 0;
602         struct process *processes;
603         int mib[2];
604
605         int total_pages;
606         int pagesize = getpagesize();
607
608         /* we get total pages count again to be sure it is up to date */
609         mib[0] = CTL_HW;
610         mib[1] = HW_USERMEM;
611         size_t size = sizeof(total_pages);
612         if(sysctl(mib, 2, &total_pages, &size, NULL, 0) == -1)
613                 fprintf(stderr, "error reading nmempages\n");
614
615         int max_size = sizeof(struct kinfo_proc2);
616         p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes);
617         processes = malloc(n_processes * sizeof (struct process));
618
619
620         for (i = 0; i < n_processes; i++) {
621                 if (!((p[i].p_flag & P_SYSTEM)) &&
622                                 p[i].p_comm != NULL) {
623                         processes[j].pid = p[i].p_pid;
624                         processes[j].name =  strdup(p[i].p_comm);
625                         processes[j].amount = 100.0 *
626                                 p[i].p_pctcpu / FSCALE;
627                         processes[j].totalmem = (float)(p[i].p_vm_rssize * pagesize /
628                                         (float)total_pages) * 100.0;
629                         j++;
630                 }
631         }
632
633         qsort(processes, j - 1, sizeof (struct process), comparemem);
634         for (i = 0; i < 10; i++) {
635                 struct process *tmp, *ttmp;
636
637                 tmp = malloc(sizeof (struct process));
638                 tmp->pid = processes[i].pid;
639                 tmp->amount = processes[i].amount;
640                 tmp->totalmem = processes[i].totalmem;
641                 tmp->name = strdup(processes[i].name);
642
643                 ttmp = mem[i];
644                 mem[i] = tmp;
645                 if (ttmp != NULL) {
646                         free(ttmp->name);
647                         free(ttmp);
648                 }
649         }
650
651         qsort(processes, j - 1, sizeof (struct process), comparecpu);
652         for (i = 0; i < 10; i++) {
653                 struct process *tmp, *ttmp;
654
655                 tmp = malloc(sizeof (struct process));
656                 tmp->pid = processes[i].pid;
657                 tmp->amount = processes[i].amount;
658                 tmp->totalmem = processes[i].totalmem;
659                 tmp->name = strdup(processes[i].name);
660
661                 ttmp = cpu[i];
662                 cpu[i] = tmp;
663                 if (ttmp != NULL) {
664                         free(ttmp->name);
665                         free(ttmp);
666                 }
667         }
668
669         for (i = 0; i < j; free(processes[i++].name));
670         free(processes);
671 }
672
673 #if     defined(i386) || defined(__i386__) 
674 #define APMDEV          "/dev/apm"
675 #define APM_UNKNOWN     255
676
677 int
678 apm_getinfo(int fd, void *null)
679 {
680         if (ioctl(fd, APM_IOC_GETPOWER) == -1)
681                 return (-1);
682
683         return (0);
684 }
685
686 char
687 *get_apm_adapter()
688 {
689         int fd;
690         struct apm_power_info info;
691
692         fd = open(APMDEV, O_RDONLY);
693         if (fd < 0)
694                 return ("ERR");
695
696         if (apm_getinfo(fd, &info) != 0) {
697                 close(fd);
698                 return ("ERR");
699         }
700         close(fd);
701
702         switch (info.ac_state) {
703                 case APM_AC_OFF:
704                         return ("off-line");
705                         break;
706                 case APM_AC_ON:
707                         if (info.battery_state == APM_BATT_CHARGING)
708                                 return ("charging");
709                         else
710                                 return ("on-line");
711                         break;
712                 default:
713                         return ("unknown");
714                         break;
715         }
716 }
717
718 char
719 *get_apm_battery_life()
720 {
721         int fd;
722         u_int batt_life;
723         struct apm_power_info info;
724         char *out;
725
726         out = (char *)calloc(16, sizeof (char));
727
728         fd = open(APMDEV, O_RDONLY);
729         if (fd < 0) {
730                 strncpy(out, "ERR", 16);
731                 return (out);
732         }
733
734         if (apm_getinfo(fd, &info) != 0) {
735                 close(fd);
736                 strncpy(out, "ERR", 16);
737                 return (out);
738         }
739         close(fd);
740
741         batt_life = info.battery_life;
742         if (batt_life <= 100) {
743                 snprintf(out, 16, "%d%%", batt_life);
744                 return (out);
745         } else
746                 strncpy(out, "ERR", 16);
747
748         return (out);
749 }
750
751 char
752 *get_apm_battery_time()
753 {
754         int fd;
755         int batt_time;
756         int h, m;
757         struct apm_power_info info;
758         char *out;
759
760         out = (char *)calloc(16, sizeof (char));
761
762         fd = open(APMDEV, O_RDONLY);
763         if (fd < 0) {
764                 strncpy(out, "ERR", 16);
765                 return (out);
766         }
767
768         if (apm_getinfo(fd, &info) != 0) {
769                 close(fd);
770                 strncpy(out, "ERR", 16);
771                 return (out);
772         }
773         close(fd);
774
775         batt_time = info.minutes_left;
776
777         if (batt_time == -1)
778                 strncpy(out, "unknown", 16);
779         else {
780                 h = batt_time / 60;
781                 m = batt_time % 60;
782                 snprintf(out, 16, "%2d:%02d", h, m);
783         }
784
785         return (out);
786 }
787
788 #endif
789
790 /* empty stubs so conky links */
791 int
792 get_battery_perct(const char *bat)
793 {
794         return (0);
795 }
796
797 int
798 get_battery_perct_bar(const char *bar)
799 {
800         return (0);
801 }
802
803 void
804 prepare_update()
805 {
806         return;
807 }
808
809 void update_entropy (void)
810 {
811         return;
812 }
813
814 void
815 free_all_processes(void)
816 {
817         return;
818 }
819
820 double
821 get_acpi_temperature(int fd)
822 {
823         return (0);
824 }
825
826 void
827 get_battery_stuff(char *buf, unsigned int n, const char *bat, int item)
828 {
829         return;
830 }
831
832 int
833 open_i2c_sensor(const char *dev, const char *type, int n, int *div,
834                 char *devtype)
835 {
836         return (0);
837 }
838
839 double
840 get_i2c_info(int *fd, int arg, char *devtype, char *type)
841 {
842         return (0);
843 }
844
845 int
846 open_acpi_temperature(const char *name)
847 {
848         return (0);
849 }
850
851 void
852 get_acpi_ac_adapter(char *p_client_buffer, size_t client_buffer_size)
853 {
854         return;
855 }
856
857 void
858 get_acpi_fan(char *p_client_buffer, size_t client_buffer_size)
859 {
860         return;
861 }
862
863 void
864 get_adt746x_cpu(char *p_client_buffer, size_t client_buffer_size)
865 {
866         return;
867 }
868
869 void
870 get_adt746x_fan(char *p_client_buffer, size_t client_buffer_size)
871 {
872         return;
873 }