Xinqi Bao's Git

30b57ab190f64b1600a6bfd84af971fd49c5cfed
[slstatus.git] / components / wifi.c
1 /* See LICENSE file for copyright and license details. */
2 #include <err.h>
3 #include <ifaddrs.h>
4 #include <linux/wireless.h>
5 #include <sys/socket.h>
6 #include <stdio.h>
7 #include <limits.h>
8 #include <string.h>
9 #include <sys/ioctl.h>
10 #include <unistd.h>
11
12 #include "../util.h"
13
14 const char *
15 wifi_perc(const char *iface)
16 {
17 int i, perc;
18 char *p, *datastart;
19 char path[PATH_MAX];
20 char status[5];
21 FILE *fp;
22
23 snprintf(path, sizeof(path), "%s%s%s", "/sys/class/net/", iface, "/operstate");
24 fp = fopen(path, "r");
25 if (fp == NULL) {
26 warn("Failed to open file %s", path);
27 return NULL;
28 }
29 p = fgets(status, 5, fp);
30 fclose(fp);
31 if(!p || strcmp(status, "up\n") != 0) {
32 return NULL;
33 }
34
35 fp = fopen("/proc/net/wireless", "r");
36 if (fp == NULL) {
37 warn("Failed to open file /proc/net/wireless");
38 return NULL;
39 }
40
41 for (i = 0; i < 3; i++) {
42 if (!(p = fgets(buf, sizeof(buf) - 1, fp)))
43 break;
44 }
45 fclose(fp);
46 if (i < 2 || !p)
47 return NULL;
48
49 if ((datastart = strstr(buf, iface)) == NULL)
50 return NULL;
51
52 datastart = (datastart+(strlen(iface)+1));
53 sscanf(datastart + 1, " %*d %d %*d %*d %*d %*d %*d %*d %*d %*d", &perc);
54
55 return bprintf("%d", perc);
56 }
57
58 const char *
59 wifi_essid(const char *iface)
60 {
61 static char id[IW_ESSID_MAX_SIZE+1];
62 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
63 struct iwreq wreq;
64
65 memset(&wreq, 0, sizeof(struct iwreq));
66 wreq.u.essid.length = IW_ESSID_MAX_SIZE+1;
67 snprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s", iface);
68
69 if (sockfd == -1) {
70 warn("Failed to get ESSID for interface %s", iface);
71 return NULL;
72 }
73 wreq.u.essid.pointer = id;
74 if (ioctl(sockfd,SIOCGIWESSID, &wreq) == -1) {
75 warn("Failed to get ESSID for interface %s", iface);
76 return NULL;
77 }
78
79 close(sockfd);
80
81 if (strcmp(id, "") == 0)
82 return NULL;
83 else
84 return id;
85 }