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 }