#include #include #include #include #include #include #include #include #include #include #define _IS_CONFIG_C #include "config.h" #undef _IS_CONFIG_C const char *wlan_interface; const char *eth_interface; const char *wmii_path; const char *time_format; const char *battery_path; bool use_colors; bool get_ethspeed; const char *wmii_normcolors = "#222222 #333333"; char order[MAX_ORDER][2]; const char **run_watches; unsigned int num_run_watches; unsigned int interval = 1; void die(const char *fmt, ...); /* * This function exists primarily for resolving ~ in pathnames. However, you * can also specify ~/Movies/ *, which will only return the first match! * */ char *glob_path(const char *path) { static glob_t globbuf; if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0) die("glob() failed"); char *result = strdup(globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : path); globfree(&globbuf); return result; } /* * Loads configuration from configfile * */ static void get_next_config_entry(FILE *handle, char **dest_name, char **dest_value, char *whole_buffer, int whole_buffer_size) { char *ret; if ((ret = fgets(whole_buffer, whole_buffer_size, handle)) == whole_buffer) { char *c = whole_buffer; /* Skip whitespaces in the beginning */ while (isspace((int)*c) && *c != '\0') c++; *dest_name = c; while (!isspace((int)*c)) c++; /* Terminate string as soon as whitespaces begin or it's terminated anyway */ *(c++) = '\0'; /* Same for the value: strip whitespaces */ while (isspace((int)*c) && *c != '\0') c++; *dest_value = c; /* Whitespace is allowed, newline/carriage return is not */ while ((*c != '\n') && (*c != '\r') && (*c != '\0')) c++; *c = 0; } else if (ret != NULL) die("Could not read line in configuration file"); } /* * Reads the configuration from the given file * */ int load_configuration(const char *configfile) { #define OPT(x) else if (strcasecmp(dest_name, x) == 0) /* Check if the file exists */ struct stat buf; if (stat(configfile, &buf) < 0) return -1; int result = 0; FILE *handle = fopen(configfile, "r"); if (handle == NULL) die("Could not open configfile"); char *dest_name = NULL, *dest_value = NULL, whole_buffer[1026]; struct stat stbuf; while (!feof(handle)) { get_next_config_entry(handle, &dest_name, &dest_value, whole_buffer, 1024); /* No more entries? We're done! */ if (dest_name == NULL) break; /* Skip comments and empty lines */ if (dest_name[0] == '#' || strlen(dest_name) < 3) continue; OPT("wlan") { wlan_interface = strdup(dest_value); } OPT("eth") { eth_interface = strdup(dest_value); } OPT("wmii_path") { char *globbed = glob_path(dest_value); if ((stat(globbed, &stbuf)) == -1) { fprintf(stderr, "Warning: wmii_path contains an invalid path\n"); free(globbed); globbed = strdup(dest_value); } if (globbed[strlen(globbed)-1] != '/') die("wmii_path is not terminated by /"); wmii_path = globbed; } OPT("time_format") { time_format = strdup(dest_value); } OPT("battery_path") { battery_path = strdup(dest_value); } OPT("run_watch") { char *name = strdup(dest_value); char *path = name; while (*path != ' ') path++; *(path++) = '\0'; num_run_watches += 2; run_watches = realloc(run_watches, sizeof(char*) * num_run_watches); run_watches[num_run_watches-2] = name; run_watches[num_run_watches-1] = path; } OPT("order") { #define SET_ORDER(opt, idx) { if (strcasecmp(token, opt) == 0) sprintf(order[idx], "%d", c++); } char *walk, *token; int c = 0; walk = token = dest_value; while (*walk != '\0') { while ((*walk != ',') && (*walk != '\0')) walk++; *(walk++) = '\0'; SET_ORDER("run", ORDER_RUN); SET_ORDER("wlan", ORDER_WLAN); SET_ORDER("eth", ORDER_ETH); SET_ORDER("battery", ORDER_BATTERY); SET_ORDER("load", ORDER_LOAD); SET_ORDER("time", ORDER_TIME); token = walk; while (isspace((int)(*token))) token++; } } OPT("color") { use_colors = true; } OPT("get_ethspeed") { get_ethspeed = true; } OPT("normcolors") { wmii_normcolors = strdup(dest_value); } OPT("interval") { interval = atoi(dest_value); } else { result = -2; die("Unknown configfile option: %s\n", dest_name); } dest_name = dest_value = NULL; } fclose(handle); if (wmii_path == NULL) exit(EXIT_FAILURE); return result; }