]> git.sur5r.net Git - i3/i3status/blob - config.c
Add code for getting process status (running/not) and load on NetBSD
[i3/i3status] / config.c
1 #include <stdio.h>
2 #include <ctype.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <stdbool.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <fcntl.h>
9 #include <glob.h>
10 #include <unistd.h>
11
12 #define _IS_CONFIG_C
13 #include "config.h"
14 #undef _IS_CONFIG_C
15
16 const char *wlan_interface;
17 const char *eth_interface;
18 const char *wmii_path;
19 const char *time_format;
20 const char *battery_path;
21 bool use_colors;
22 bool get_ethspeed;
23 const char *wmii_normcolors = "#222222 #333333";
24 char order[MAX_ORDER][2];
25 const char **run_watches;
26 unsigned int num_run_watches;
27 unsigned int interval = 1;
28
29 void die(const char *fmt, ...);
30
31 /*
32  * This function exists primarily for resolving ~ in pathnames. However, you
33  * can also specify ~/Movies/ *, which will only return the first match!
34  *
35  */
36 char *glob_path(const char *path) {
37         static glob_t globbuf;
38         if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0)
39                 die("glob() failed");
40         char *result = strdup(globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : path);
41         globfree(&globbuf);
42         return result;
43 }
44
45 /*
46  * Loads configuration from configfile
47  *
48  */
49 static void get_next_config_entry(FILE *handle, char **dest_name, char **dest_value, char *whole_buffer, int whole_buffer_size) {
50         char *ret;
51         if ((ret = fgets(whole_buffer, whole_buffer_size, handle)) == whole_buffer) {
52                 char *c = whole_buffer;
53                 /* Skip whitespaces in the beginning */
54                 while (isspace((int)*c) && *c != '\0')
55                         c++;
56                 *dest_name = c;
57                 while (!isspace((int)*c))
58                         c++;
59                 /* Terminate string as soon as whitespaces begin or it's terminated anyway */
60                 *(c++) = '\0';
61
62                 /* Same for the value: strip whitespaces */
63                 while (isspace((int)*c) && *c != '\0')
64                         c++;
65                 *dest_value = c;
66                 /* Whitespace is allowed, newline/carriage return is not */
67                 while ((*c != '\n') && (*c != '\r') && (*c != '\0'))
68                         c++;
69                 *c = 0;
70         } else if (ret != NULL)
71                 die("Could not read line in configuration file");
72 }
73
74 /*
75  * Reads the configuration from the given file
76  *
77  */
78 int load_configuration(const char *configfile) {
79         #define OPT(x) else if (strcasecmp(dest_name, x) == 0)
80
81         /* Check if the file exists */
82         struct stat buf;
83         if (stat(configfile, &buf) < 0)
84                 return -1;
85
86         int result = 0;
87         FILE *handle = fopen(configfile, "r");
88         if (handle == NULL)
89                 die("Could not open configfile");
90         char *dest_name = NULL, *dest_value = NULL, whole_buffer[1026];
91         struct stat stbuf;
92         while (!feof(handle)) {
93                 get_next_config_entry(handle, &dest_name, &dest_value, whole_buffer, 1024);
94                 /* No more entries? We're done! */
95                 if (dest_name == NULL)
96                         break;
97                 /* Skip comments and empty lines */
98                 if (dest_name[0] == '#' || strlen(dest_name) < 3)
99                         continue;
100
101                 OPT("wlan")
102                 {
103                         wlan_interface = strdup(dest_value);
104                 }
105                 OPT("eth")
106                 {
107                         eth_interface = strdup(dest_value);
108                 }
109                 OPT("wmii_path")
110                 {
111                         char *globbed = glob_path(dest_value);
112                         if ((stat(globbed, &stbuf)) == -1) {
113                                 fprintf(stderr, "Warning: wmii_path contains an invalid path\n");
114                                 free(globbed);
115                                 globbed = strdup(dest_value);
116                         }
117                         if (globbed[strlen(globbed)-1] != '/')
118                                 die("wmii_path is not terminated by /");
119                         wmii_path = globbed;
120                 }
121                 OPT("time_format")
122                 {
123                         time_format = strdup(dest_value);
124                 }
125                 OPT("battery_path")
126                 {
127                         battery_path = strdup(dest_value);
128                 }
129                 OPT("run_watch")
130                 {
131                         char *name = strdup(dest_value);
132                         char *path = name;
133                         while (*path != ' ')
134                                 path++;
135                         *(path++) = '\0';
136                         num_run_watches += 2;
137                         run_watches = realloc(run_watches, sizeof(char*) * num_run_watches);
138                         run_watches[num_run_watches-2] = name;
139                         run_watches[num_run_watches-1] = path;
140                 }
141                 OPT("order")
142                 {
143                         #define SET_ORDER(opt, idx) { if (strcasecmp(token, opt) == 0) sprintf(order[idx], "%d", c++); }
144                         char *walk, *token;
145                         int c = 0;
146                         walk = token = dest_value;
147                         while (*walk != '\0') {
148                                 while ((*walk != ',') && (*walk != '\0'))
149                                         walk++;
150                                 *(walk++) = '\0';
151                                 SET_ORDER("run", ORDER_RUN);
152                                 SET_ORDER("wlan", ORDER_WLAN);
153                                 SET_ORDER("eth", ORDER_ETH);
154                                 SET_ORDER("battery", ORDER_BATTERY);
155                                 SET_ORDER("load", ORDER_LOAD);
156                                 SET_ORDER("time", ORDER_TIME);
157                                 token = walk;
158                                 while (isspace((int)(*token)))
159                                         token++;
160                         }
161                 }
162                 OPT("color")
163                 {
164                         use_colors = true;
165                 }
166                 OPT("get_ethspeed")
167                 {
168                         get_ethspeed = true;
169                 }
170                 OPT("normcolors")
171                 {
172                         wmii_normcolors = strdup(dest_value);
173                 }
174                 OPT("interval")
175                 {
176                         interval = atoi(dest_value);
177                 }
178                 else
179                 {
180                         result = -2;
181                         die("Unknown configfile option: %s\n", dest_name);
182                 }
183                 dest_name = dest_value = NULL;
184         }
185         fclose(handle);
186
187         if (wmii_path == NULL)
188                 exit(EXIT_FAILURE);
189
190         return result;
191 }