slstatus.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* See LICENSE file for copyright and license details. */
  2. #include <err.h>
  3. #include <errno.h>
  4. #include <locale.h>
  5. #include <signal.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <X11/Xlib.h>
  11. #include "arg.h"
  12. #include "util.h"
  13. struct arg {
  14. const char *(*func)();
  15. const char *fmt;
  16. const char *args;
  17. };
  18. static const char *battery_perc(const char *bat);
  19. static const char *battery_power(const char *bat);
  20. static const char *battery_state(const char *bat);
  21. static const char *cpu_freq(void);
  22. static const char *cpu_perc(void);
  23. static const char *cpu_iowait(void);
  24. static const char *datetime(const char *fmt);
  25. static const char *disk_free(const char *mnt);
  26. static const char *disk_perc(const char *mnt);
  27. static const char *disk_total(const char *mnt);
  28. static const char *disk_used(const char *mnt);
  29. static const char *entropy(void);
  30. static const char *gid(void);
  31. static const char *hostname(void);
  32. static const char *ipv4(const char *iface);
  33. static const char *ipv6(const char *iface);
  34. static const char *kernel_release(void);
  35. static const char *keyboard_indicators(void);
  36. static const char *load_avg(const char *fmt);
  37. static const char *num_files(const char *dir);
  38. static const char *ram_free(void);
  39. static const char *ram_perc(void);
  40. static const char *ram_used(void);
  41. static const char *ram_total(void);
  42. static const char *run_command(const char *cmd);
  43. static const char *swap_free(void);
  44. static const char *swap_perc(void);
  45. static const char *swap_used(void);
  46. static const char *swap_total(void);
  47. static const char *temp(const char *file);
  48. static const char *uid(void);
  49. static const char *uptime(void);
  50. static const char *username(void);
  51. static const char *vol_perc(const char *card);
  52. static const char *wifi_perc(const char *iface);
  53. static const char *wifi_essid(const char *iface);
  54. char *argv0;
  55. static unsigned short int done;
  56. static Display *dpy;
  57. #include "config.h"
  58. static void
  59. terminate(const int signo)
  60. {
  61. done = 1;
  62. }
  63. static void
  64. difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
  65. {
  66. res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec);
  67. res->tv_nsec = a->tv_nsec - b->tv_nsec +
  68. (a->tv_nsec < b->tv_nsec) * 1000000000;
  69. }
  70. static void
  71. usage(void)
  72. {
  73. fprintf(stderr, "usage: %s [-s]\n", argv0);
  74. exit(1);
  75. }
  76. int
  77. main(int argc, char *argv[])
  78. {
  79. struct sigaction act;
  80. struct timespec start, current, diff, intspec, wait;
  81. size_t i, len;
  82. int sflag = 0;
  83. char status[MAXLEN];
  84. ARGBEGIN {
  85. case 's':
  86. sflag = 1;
  87. break;
  88. default:
  89. usage();
  90. } ARGEND
  91. if (argc) {
  92. usage();
  93. }
  94. setlocale(LC_ALL, "");
  95. memset(&act, 0, sizeof(act));
  96. act.sa_handler = terminate;
  97. sigaction(SIGINT, &act, NULL);
  98. sigaction(SIGTERM, &act, NULL);
  99. if (!sflag && !(dpy = XOpenDisplay(NULL))) {
  100. fprintf(stderr, "slstatus: cannot open display");
  101. return 1;
  102. }
  103. while (!done) {
  104. clock_gettime(CLOCK_MONOTONIC, &start);
  105. status[0] = '\0';
  106. for (i = len = 0; i < LEN(args); i++) {
  107. len += snprintf(status + len, sizeof(status) - len,
  108. args[i].fmt, args[i].func(args[i].args));
  109. if (len >= sizeof(status)) {
  110. status[sizeof(status) - 1] = '\0';
  111. }
  112. }
  113. if (sflag) {
  114. printf("%s\n", status);
  115. } else {
  116. XStoreName(dpy, DefaultRootWindow(dpy), status);
  117. XSync(dpy, False);
  118. }
  119. if (!done) {
  120. clock_gettime(CLOCK_MONOTONIC, &current);
  121. difftimespec(&diff, &current, &start);
  122. intspec.tv_sec = interval / 1000;
  123. intspec.tv_nsec = (interval % 1000) * 1000000;
  124. difftimespec(&wait, &intspec, &diff);
  125. if (wait.tv_sec >= 0) {
  126. nanosleep(&wait, NULL);
  127. }
  128. }
  129. }
  130. if (!sflag) {
  131. XStoreName(dpy, DefaultRootWindow(dpy), NULL);
  132. XCloseDisplay(dpy);
  133. }
  134. return 0;
  135. }