My slstatus configuration
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

273 linhas
5.8 KiB

  1. /* See LICENSE file for copyright and license details. */
  2. #include <ifaddrs.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/ioctl.h>
  6. #include <sys/socket.h>
  7. #include <unistd.h>
  8. #include "../util.h"
  9. #define RSSI_TO_PERC(rssi) \
  10. rssi >= -50 ? 100 : \
  11. (rssi <= -100 ? 0 : \
  12. (2 * (rssi + 100)))
  13. #if defined(__linux__)
  14. #include <limits.h>
  15. #include <linux/wireless.h>
  16. const char *
  17. wifi_perc(const char *interface)
  18. {
  19. int cur;
  20. size_t i;
  21. char *p, *datastart;
  22. char path[PATH_MAX];
  23. char status[5];
  24. FILE *fp;
  25. if (esnprintf(path, sizeof(path), "/sys/class/net/%s/operstate",
  26. interface) < 0) {
  27. return NULL;
  28. }
  29. if (!(fp = fopen(path, "r"))) {
  30. warn("fopen '%s':", path);
  31. return NULL;
  32. }
  33. p = fgets(status, 5, fp);
  34. fclose(fp);
  35. if (!p || strcmp(status, "up\n") != 0) {
  36. return NULL;
  37. }
  38. if (!(fp = fopen("/proc/net/wireless", "r"))) {
  39. warn("fopen '/proc/net/wireless':");
  40. return NULL;
  41. }
  42. for (i = 0; i < 3; i++) {
  43. if (!(p = fgets(buf, sizeof(buf) - 1, fp)))
  44. break;
  45. }
  46. fclose(fp);
  47. if (i < 2 || !p) {
  48. return NULL;
  49. }
  50. if (!(datastart = strstr(buf, interface))) {
  51. return NULL;
  52. }
  53. datastart = (datastart+(strlen(interface)+1));
  54. sscanf(datastart + 1, " %*d %d %*d %*d\t\t %*d\t "
  55. "%*d\t\t%*d\t\t %*d\t %*d\t\t %*d", &cur);
  56. /* 70 is the max of /proc/net/wireless */
  57. return bprintf("%d", (int)((float)cur / 70 * 100));
  58. }
  59. const char *
  60. wifi_essid(const char *interface)
  61. {
  62. static char id[IW_ESSID_MAX_SIZE+1];
  63. int sockfd;
  64. struct iwreq wreq;
  65. memset(&wreq, 0, sizeof(struct iwreq));
  66. wreq.u.essid.length = IW_ESSID_MAX_SIZE+1;
  67. if (esnprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s",
  68. interface) < 0) {
  69. return NULL;
  70. }
  71. if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  72. warn("socket 'AF_INET':");
  73. return NULL;
  74. }
  75. wreq.u.essid.pointer = id;
  76. if (ioctl(sockfd,SIOCGIWESSID, &wreq) < 0) {
  77. warn("ioctl 'SIOCGIWESSID':");
  78. close(sockfd);
  79. return NULL;
  80. }
  81. close(sockfd);
  82. if (!strcmp(id, "")) {
  83. return NULL;
  84. }
  85. return id;
  86. }
  87. #elif defined(__OpenBSD__)
  88. #include <net/if.h>
  89. #include <net/if_media.h>
  90. #include <net80211/ieee80211.h>
  91. #include <sys/select.h> /* before <sys/ieee80211_ioctl.h> for NBBY */
  92. #include <net80211/ieee80211_ioctl.h>
  93. #include <stdlib.h>
  94. #include <sys/types.h>
  95. static int
  96. load_ieee80211_nodereq(const char *interface, struct ieee80211_nodereq *nr)
  97. {
  98. struct ieee80211_bssid bssid;
  99. int sockfd;
  100. uint8_t zero_bssid[IEEE80211_ADDR_LEN];
  101. memset(&bssid, 0, sizeof(bssid));
  102. memset(nr, 0, sizeof(struct ieee80211_nodereq));
  103. if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  104. warn("socket 'AF_INET':");
  105. return 0;
  106. }
  107. strlcpy(bssid.i_name, interface, sizeof(bssid.i_name));
  108. if ((ioctl(sockfd, SIOCG80211BSSID, &bssid)) < 0) {
  109. warn("ioctl 'SIOCG80211BSSID':");
  110. close(sockfd);
  111. return 0;
  112. }
  113. memset(&zero_bssid, 0, sizeof(zero_bssid));
  114. if (memcmp(bssid.i_bssid, zero_bssid,
  115. IEEE80211_ADDR_LEN) == 0) {
  116. close(sockfd);
  117. return 0;
  118. }
  119. strlcpy(nr->nr_ifname, interface, sizeof(nr->nr_ifname));
  120. memcpy(&nr->nr_macaddr, bssid.i_bssid, sizeof(nr->nr_macaddr));
  121. if ((ioctl(sockfd, SIOCG80211NODE, nr)) < 0 && nr->nr_rssi) {
  122. warn("ioctl 'SIOCG80211NODE':");
  123. close(sockfd);
  124. return 0;
  125. }
  126. return close(sockfd), 1;
  127. }
  128. const char *
  129. wifi_perc(const char *interface)
  130. {
  131. struct ieee80211_nodereq nr;
  132. int q;
  133. if (load_ieee80211_nodereq(interface, &nr)) {
  134. if (nr.nr_max_rssi) {
  135. q = IEEE80211_NODEREQ_RSSI(&nr);
  136. } else {
  137. q = RSSI_TO_PERC(nr.nr_rssi);
  138. }
  139. return bprintf("%d", q);
  140. }
  141. return NULL;
  142. }
  143. const char *
  144. wifi_essid(const char *interface)
  145. {
  146. struct ieee80211_nodereq nr;
  147. if (load_ieee80211_nodereq(interface, &nr)) {
  148. return bprintf("%s", nr.nr_nwid);
  149. }
  150. return NULL;
  151. }
  152. #elif defined(__FreeBSD__)
  153. #include <net/if.h>
  154. #include <net80211/ieee80211_ioctl.h>
  155. int
  156. load_ieee80211req(int sock, const char *interface, void *data, int type, size_t *len)
  157. {
  158. char warn_buf[256];
  159. struct ieee80211req ireq;
  160. memset(&ireq, 0, sizeof(ireq));
  161. ireq.i_type = type;
  162. ireq.i_data = (caddr_t) data;
  163. ireq.i_len = *len;
  164. strlcpy(ireq.i_name, interface, sizeof(ireq.i_name));
  165. if (ioctl(sock, SIOCG80211, &ireq) < 0) {
  166. snprintf(warn_buf, sizeof(warn_buf),
  167. "ioctl: 'SIOCG80211': %d", type);
  168. warn(warn_buf);
  169. return 0;
  170. }
  171. *len = ireq.i_len;
  172. return 1;
  173. }
  174. const char *
  175. wifi_perc(const char *interface)
  176. {
  177. union {
  178. struct ieee80211req_sta_req sta;
  179. uint8_t buf[24 * 1024];
  180. } info;
  181. uint8_t bssid[IEEE80211_ADDR_LEN];
  182. int rssi_dbm;
  183. int sockfd;
  184. size_t len;
  185. const char *fmt;
  186. if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  187. warn("socket 'AF_INET':");
  188. return NULL;
  189. }
  190. /* Retreive MAC address of interface */
  191. len = IEEE80211_ADDR_LEN;
  192. fmt = NULL;
  193. if (load_ieee80211req(sockfd, interface, &bssid, IEEE80211_IOC_BSSID, &len))
  194. {
  195. /* Retrieve info on station with above BSSID */
  196. memset(&info, 0, sizeof(info));
  197. memcpy(info.sta.is_u.macaddr, bssid, sizeof(bssid));
  198. len = sizeof(info);
  199. if (load_ieee80211req(sockfd, interface, &info, IEEE80211_IOC_STA_INFO, &len)) {
  200. rssi_dbm = info.sta.info[0].isi_noise +
  201. info.sta.info[0].isi_rssi / 2;
  202. fmt = bprintf("%d", RSSI_TO_PERC(rssi_dbm));
  203. }
  204. }
  205. close(sockfd);
  206. return fmt;
  207. }
  208. const char *
  209. wifi_essid(const char *interface)
  210. {
  211. char ssid[IEEE80211_NWID_LEN + 1];
  212. size_t len;
  213. int sockfd;
  214. const char *fmt;
  215. if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  216. warn("socket 'AF_INET':");
  217. return NULL;
  218. }
  219. fmt = NULL;
  220. len = sizeof(ssid);
  221. memset(&ssid, 0, len);
  222. if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len )) {
  223. if (len < sizeof(ssid))
  224. len += 1;
  225. else
  226. len = sizeof(ssid);
  227. ssid[len - 1] = '\0';
  228. fmt = bprintf("%s", ssid);
  229. }
  230. close(sockfd);
  231. return fmt;
  232. }
  233. #endif