t* dwmstatus for OpenBSD
URI git clone git://git.codevoid.de/dwmstatus-sdk
DIR Log
DIR Files
DIR Refs
DIR LICENSE
---
tdwmstatus.c (6770B)
---
1 // Copy me if you can.
2 // by 20h
3
4 #define _BSD_SOURCE
5 #include <unistd.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdarg.h>
9 #include <string.h>
10 #include <sys/time.h>
11 #include <sys/sysctl.h>
12 #include <sys/ioctl.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <ifaddrs.h>
16 #include <fcntl.h>
17 #include <X11/Xlib.h>
18 #include <sys/param.h>
19 #include <sys/mount.h>
20 #ifdef __linux__
21 #include <sys/statfs.h>
22 #include <time.h>
23 #else
24 #include <sys/sensors.h>
25 #include <sys/audioio.h>
26 #include <machine/apmvar.h>
27
28 #endif
29
30 // configuration
31 #define UPDATE_INTERVAL 10
32
33 // conversation presets
34 #define ZEROCTOC(x) ((x)-2731) / 10
35 #define BTOMB(x) ((x)*1048576
36 #define BTOGB(x) ((x)*1073741824
37
38 static Display *dpy;
39 char *tzlocal = "Europe/Berlin";
40
41 char * smprintf(char *fmt, ...) {
42 va_list fmtargs;
43 char *ret;
44 int len;
45
46 va_start(fmtargs, fmt);
47 len = vsnprintf(NULL, 0, fmt, fmtargs);
48 va_end(fmtargs);
49
50 ret = malloc(++len);
51 if (ret == NULL) {
52 perror("malloc");
53 exit(1);
54 }
55
56 va_start(fmtargs, fmt);
57 vsnprintf(ret, len, fmt, fmtargs);
58 va_end(fmtargs);
59
60 return ret;
61 }
62
63 char * getfreespace(const char *path) {
64 struct statfs vfs;
65 statfs(path, &vfs);
66 return smprintf("%ld", (vfs.f_bavail * vfs.f_bsize) / 1024 / 1024);
67 }
68
69 #ifdef __OpenBSD__
70 char * getcputemp() {
71 struct sensor sensor;
72 size_t slen = sizeof(sensor);
73 int mib[5] = { CTL_HW, HW_SENSORS, 0, SENSOR_TEMP, 0 }; // Lenovo x230
74 if (sysctl(mib, 5, &sensor, &slen, NULL, 0) != -1)
75 return smprintf("%.0f", (sensor.value - 273150000) / 1000000.0);
76 return smprintf("err");
77 }
78 #endif
79
80 #ifdef __OpenBSD__
81 char * getfan() {
82 struct sensor sensor;
83 size_t slen = sizeof(sensor);
84 int mib[5] = { CTL_HW, HW_SENSORS, 5, SENSOR_FANRPM, 0 }; // Lenovo x230
85 if (sysctl(mib, 5, &sensor, &slen, NULL, 0) != -1)
86 return smprintf("%i", sensor.value);
87 return smprintf("err");
88 }
89 #endif
90
91 #ifdef __OpenBSD__
92 char * getvolume() {
93 static int cls = -1, fd, v;
94 static struct mixer_devinfo mdi;
95 static struct mixer_ctrl mc;
96
97 if ((fd = open("/dev/mixer", O_RDONLY)) == -1)
98 return smprintf("NOMIXER");
99
100 for (mdi.index = 0; cls == -1; ++mdi.index) {
101 if (ioctl(fd, AUDIO_MIXER_DEVINFO, &mdi) == -1)
102 goto fail;
103 if (mdi.type == AUDIO_MIXER_CLASS &&
104 strcmp(mdi.label.name, AudioCoutputs) == 0)
105 cls = mdi.index;
106 }
107 for (mdi.index = 0, v = -1; v == -1; ++mdi.index) {
108 if (ioctl(fd, AUDIO_MIXER_DEVINFO, &mdi) == -1)
109 goto fail;
110 if (mdi.type == AUDIO_MIXER_VALUE &&
111 mdi.prev == AUDIO_MIXER_LAST &&
112 mdi.mixer_class == cls &&
113 strcmp(mdi.label.name, AudioNmaster) == 0) {
114 mc.dev = mdi.index;
115 if (ioctl(fd, AUDIO_MIXER_READ, &mc) == -1)
116 goto fail;
117 v = MAX(mc.un.value.level[AUDIO_MIXER_LEVEL_MONO],
118 mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
119 }
120 }
121
122 if (v == -1 || close(fd) == -1)
123 return smprintf("NOCHAN");
124
125 return smprintf("%i", v * 100 / 255);
126
127 fail:
128 (void)close(fd);
129 return smprintf("FAILED");
130 }
131 #endif
132
133 void settz(char *tzname) {
134 setenv("TZ", tzname, 1);
135 }
136
137 char * mktimes(char *fmt, char *tzname) {
138 char buf[129];
139 time_t tim;
140 struct tm *timtm;
141
142 settz(tzname);
143 tim = time(NULL);
144 timtm = localtime(&tim);
145 if (timtm == NULL)
146 return smprintf("");
147
148 if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) {
149 fprintf(stderr, "strftime == 0\n");
150 return smprintf("");
151 }
152
153 return smprintf("%s", buf);
154 }
155
156 void setstatus(char *str) {
157 XStoreName(dpy, DefaultRootWindow(dpy), str);
158 XSync(dpy, False);
159 }
160
161 char * loadavg(int i) {
162 double avgs[3];
163
164 if (getloadavg(avgs, 3) < 0)
165 return smprintf("");
166
167 //return smprintf("%.2f|%.2f|%.2f", avgs[0], avgs[1], avgs[2]);
168 return smprintf("%.2f", avgs[i]);
169 }
170
171 char * readfile(char *base, char *file) {
172 char *path, line[513];
173 FILE *fd;
174
175 memset(line, 0, sizeof(line));
176
177 path = smprintf("%s/%s", base, file);
178 fd = fopen(path, "r");
179 free(path);
180 if (fd == NULL)
181 return NULL;
182
183 if (fgets(line, sizeof(line)-1, fd) == NULL)
184 return NULL;
185 fclose(fd);
186
187 return smprintf("%s", line);
188 }
189
190 #ifdef __OpenBSD__
191 char * getbattery()
192 {
193 int fd;
194 struct apm_power_info pi;
195
196 if ((fd = open("/dev/apm", O_RDONLY)) == -1 ||
197 ioctl(fd, APM_IOC_GETPOWER, &pi) == -1 ||
198 close(fd) == -1)
199 return smprintf("battery");
200
201 if (pi.battery_state == APM_BATT_UNKNOWN ||
202 pi.battery_state == APM_BATTERY_ABSENT)
203 return smprintf("no battery");
204
205 return smprintf("%i", pi.battery_life);
206 }
207 #endif
208
209 char * getifaddr(char * intf)
210 {
211 struct ifaddrs *addrs;
212 getifaddrs(&addrs);
213
214 while (addrs)
215 {
216 if (addrs->ifa_addr && strcmp(addrs->ifa_name,intf)
217 && addrs->ifa_addr->sa_family == AF_INET)
218 {
219 struct sockaddr * myaddr = addrs->ifa_addr;
220 return smprintf("%x", myaddr);
221 }
222 addrs = addrs->ifa_next;
223 }
224 freeifaddrs(addrs);
225 return smprintf("n/a");
226 }
227
228 // update all values and print statusbar
229 void update() {
230
231 // date and time (local)
232 char *time = mktimes("%H:%M", tzlocal);
233 char *date = mktimes("%a %Y-%m-%d", tzlocal);
234
235 // display status
236 #ifdef __linux__
237 char *freehomespace = getfreespace("/home");
238 setstatus(smprintf(
239 "SPACE: %.2fG | LOAD: %s | %s %s",
240 (float)atoi(freehomespace) / 1024, loadavg(0), date, time));
241 free(freehomespace);
242 #else
243 char *freehomespace = getfreespace("/home");
244 char *freedataspace = getfreespace("/data");
245 setstatus(smprintf(
246 "H:%.2fG D:%.2fG š %s%% š %s%% š„ %s°C š %sRPM š %s @ %s",
247 (float)atoi(freehomespace) / 1024, (float)atoi(freedataspace) / 1024,
248 getbattery(), getvolume(), getcputemp(), getfan(), loadavg(0), time));
249 free(freehomespace);
250 free(freedataspace);
251 #endif
252 free(time);
253 free(date);
254
255 // free everything up
256 }
257
258 void sig_handler(int signo) {
259 if (signo == SIGUSR1)
260 update();
261 usleep(50000);
262 }
263
264 int main(void) {
265
266 if (!(dpy = XOpenDisplay(NULL))) {
267 fprintf(stderr, "dwmstatus: cannot open display.\n");
268 return 1;
269 }
270
271 // register signal handler
272 if (signal(SIGUSR1, sig_handler) == SIG_ERR) {
273 fprintf(stderr, "Err: can't register update signal (SIGUSR1)\n");
274 return 1;
275 }
276
277 // update status
278 for (;;sleep(UPDATE_INTERVAL)) {
279 update();
280 }
281
282 XCloseDisplay(dpy);
283
284 return 0;
285 }