diff options
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | config.c | 178 | ||||
| -rw-r--r-- | config.h | 39 | ||||
| -rw-r--r-- | wmiistatus.c | 92 | ||||
| -rw-r--r-- | wmiistatus.h | 6 | 
5 files changed, 268 insertions, 54 deletions
| @@ -1,10 +1,13 @@ -wmiistatus: wmiistatus.c wmiistatus.h config.h Makefile -	gcc -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare -g -O2 -o wmiistatus wmiistatus.c +wmiistatus: wmiistatus.c wmiistatus.h config.h config.c Makefile +	gcc -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare -g -c -o wmiistatus.o wmiistatus.c +	gcc -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare -g -c -o config.o config.c +	gcc -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare -g -o wmiistatus *.o  install:  	install -m 755 -d $(DESTDIR)/usr/bin  	install -m 755 -d $(DESTDIR)/etc/init.d  	install -m 755 wmiistatus $(DESTDIR)/usr/bin/wmiistatus  	install -m 755 wmiistatus.init $(DESTDIR)/etc/init.d/wmiistatus +	install -m 644 wmiistatus.conf $(DESTDIR)/etc/wmiistatus.conf  all: wmiistatus diff --git a/config.c b/config.c new file mode 100644 index 0000000..bc1ec4f --- /dev/null +++ b/config.c @@ -0,0 +1,178 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <glob.h> +#include <unistd.h> + +#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; +const char *wmii_normcolors; +char order[MAX_ORDER][2]; +const char **run_watches; +unsigned int num_run_watches; + +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) +				die("wmii_path contains an invalid path"); +			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") +		{ +			if ((stat(dest_value, &stbuf)) == -1) +				die("battery_path contains an invalid 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; +			} +		} +		OPT("color") +		{ +			use_colors = true; +		} +		OPT("normcolors") +		{ +			wmii_normcolors = strdup(dest_value); +		} +		else +		{ +			result = -2; +			die("Unknown configfile option: %s\n", dest_name); +		} +		dest_name = dest_value = NULL; +	} +	fclose(handle); + +	if (wmii_path == NULL) +		die("No wmii_path specified in configuration file"); + +	return result; +} @@ -1,18 +1,25 @@ -const char *wlan_interface = "wlan0"; -const char *eth_interface = "eth0"; -/* wmii_path has to be terminated by slash */ -const char *wmii_path = "/mnt/wmii/rbar/"; -const char *time_format = "%d.%m.%Y %H:%M:%S"; -const char *battery = "/sys/class/power_supply/BAT0/uevent"; -const char *run_watches[] = {"DHCP", "/var/run/dhclient.pid", -			     "VPN", "/var/run/vpnc*.pid"}; +#include <stdbool.h> -#define ORDER_RUN	"0" -#define ORDER_WLAN 	"1" -#define ORDER_ETH 	"2" -#define ORDER_BATTERY 	"3" -#define ORDER_LOAD 	"4" -#define ORDER_TIME 	"5" +#ifndef _CONFIG_H +#define _CONFIG_H -#define USE_COLORS -#define WMII_NORMCOLORS "#000000 #333333" /* <background> <border> */ +enum { ORDER_RUN, ORDER_WLAN, ORDER_ETH, ORDER_BATTERY, ORDER_LOAD, ORDER_TIME, MAX_ORDER }; + +#ifndef _IS_CONFIG_C /* Definitions for everybody */ +extern const char *wlan_interface; +extern const char *eth_interface; +extern const char *wmii_path; +extern const char *time_format; +extern const char *battery_path; +extern const char **run_watches; +extern unsigned int num_run_watches; +extern const char *wmii_normcolors; +extern const char order[MAX_ORDER][2]; + +extern bool use_colors; +#endif + +char *glob_path(const char *path); +int load_configuration(const char *configfile); + +#endif diff --git a/wmiistatus.c b/wmiistatus.c index 44d13a4..a658f81 100644 --- a/wmiistatus.c +++ b/wmiistatus.c @@ -50,9 +50,23 @@  #include <glob.h>  #include <dirent.h> +#define _IS_WMIISTATUS_C  #include "wmiistatus.h" +#undef _IS_WMIISTATUS_C  #include "config.h" +/* + * This function just concats two strings in place, it should only be used + * for concatting order to the name of a file or concatting color codes. + * Otherwise, the buffer size would have to be increased. + * + */ +static char *concat(const char *str1, const char *str2) { +	static char concatbuf[32]; +	snprintf(concatbuf, sizeof(concatbuf), "%s%s", str1, str2); +	return concatbuf; +} +  static void cleanup_rbar_dir() {  	struct dirent *ent;  	DIR *dir; @@ -78,9 +92,10 @@ static void create_file(const char *name) {  	int fd = creat(pathbuf, S_IRUSR | S_IWUSR);  	if (fd < 0)  		exit(-4); -#ifdef USE_COLORS -	write(fd, "#888888 " WMII_NORMCOLORS, strlen("#888888 " WMII_NORMCOLORS)); -#endif +	if (use_colors) { +		char *tmp = concat("#888888 ", wmii_normcolors); +		write(fd, tmp, strlen(tmp)); +	}  	close(fd);  } @@ -97,6 +112,7 @@ static void write_to_statusbar(const char *name, const char *message) {  static void write_error_to_statusbar(const char *message) {  	cleanup_rbar_dir(); +	create_file("error");  	write_to_statusbar("error", message);  } @@ -104,7 +120,7 @@ static void write_error_to_statusbar(const char *message) {   * Write errormessage to statusbar and exit   *   */ -static void die(const char *fmt, ...) { +void die(const char *fmt, ...) {  	char buffer[512];  	va_list ap;  	va_start(ap, fmt); @@ -136,9 +152,9 @@ static char *get_battery_info() {  	char buf[1024];  	static char part[512];  	char *walk, *last = buf; -	int fd = open(battery, O_RDONLY); +	int fd = open(battery_path, O_RDONLY);  	if (fd == -1) -		die("Could not open %s", battery); +		die("Could not open %s", battery_path);  	int full_design = -1,  	    remaining = -1,  	    present_rate = -1; @@ -215,11 +231,9 @@ static char *get_wireless_info() {  			int quality = atoi(interfaces);  			/* For some reason, I get 255 sometimes */  			if ((quality == 255) || (quality == 0)) { -#ifdef USE_COLORS -			snprintf(part, sizeof(part), "#FF0000 " WMII_NORMCOLORS " W: down"); -#else -			snprintf(part, sizeof(part), "W: down"); -#endif +			if (use_colors) +				snprintf(part, sizeof(part), "%s%s", concat("#FF0000 ", wmii_normcolors), " W: down"); +			else snprintf(part, sizeof(part), "W: down");  			} else {  				snprintf(part, sizeof(part), "W: (%02d%%) ", quality); @@ -315,32 +329,38 @@ int main(void) {  	     *end;  	unsigned int i; +	load_configuration("/etc/wmiistatus.conf");  	cleanup_rbar_dir(); -	create_file(ORDER_WLAN "wlan"); -	create_file(ORDER_ETH "eth"); -	create_file(ORDER_BATTERY "battery"); -	create_file(ORDER_LOAD "load"); -	create_file(ORDER_TIME "time"); -	for (i = 0; i < sizeof(run_watches) / sizeof(char*); i += 2) { -		sprintf(pathbuf, "%s%s", ORDER_RUN, run_watches[i]); +	if (wlan_interface) +		create_file(concat(order[ORDER_WLAN],"wlan")); +	if (eth_interface) +		create_file(concat(order[ORDER_ETH],"eth")); +	if (battery_path) +		create_file(concat(order[ORDER_BATTERY],"battery")); +	create_file(concat(order[ORDER_LOAD],"load")); +	if (time_format) +		create_file(concat(order[ORDER_TIME],"time")); +	for (i = 0; i < num_run_watches; i += 2) { +		sprintf(pathbuf, "%s%s", order[ORDER_RUN], run_watches[i]);  		create_file(pathbuf);  	}  	while (1) { -		for (i = 0; i < sizeof(run_watches) / sizeof(char*); i += 2) { +		for (i = 0; i < num_run_watches; i += 2) {  			bool running = process_runs(run_watches[i+1]); -#ifdef USE_COLORS -			sprintf(part, "%s %s: %s", (running ? "#00FF00 " WMII_NORMCOLORS : "#FF0000 " WMII_NORMCOLORS), run_watches[i], (running ? "yes" : "no")); -#else -			sprintf(part, "%s: %s", run_watches[i], (running ? "yes" : "no")); -#endif -			sprintf(pathbuf, "%s%s", ORDER_RUN, run_watches[i]); +			if (use_colors) +				sprintf(part, "%s %s: %s", (running ? concat("#00FF00 ", wmii_normcolors) : concat("#FF0000 ", wmii_normcolors)), run_watches[i], (running ? "yes" : "no")); +			else sprintf(part, "%s: %s", run_watches[i], (running ? "yes" : "no")); +			sprintf(pathbuf, "%s%s", order[ORDER_RUN], run_watches[i]);  			write_to_statusbar(pathbuf, part);  		} -		write_to_statusbar(ORDER_WLAN "wlan", get_wireless_info()); -		write_to_statusbar(ORDER_ETH "eth", get_eth_info()); -		write_to_statusbar(ORDER_BATTERY "battery", get_battery_info()); +		if (wlan_interface) +			write_to_statusbar(concat(order[ORDER_WLAN], "wlan"), get_wireless_info()); +		if (eth_interface) +			write_to_statusbar(concat(order[ORDER_ETH], "eth"), get_eth_info()); +		if (battery_path) +			write_to_statusbar(concat(order[ORDER_BATTERY], "battery"), get_battery_info());  		/* Get load */  		int load_avg = open("/proc/loadavg", O_RDONLY); @@ -350,13 +370,15 @@ int main(void) {  		close(load_avg);  		end = skip_character(part, ' ', 3);  		*end = '\0'; -		write_to_statusbar(ORDER_LOAD "load", part); - -		/* Get date & time */ -		time_t current_time = time(NULL); -		struct tm *current_tm = localtime(¤t_time); -		strftime(part, sizeof(part), time_format, current_tm); -		write_to_statusbar(ORDER_TIME "time", part); +		write_to_statusbar(concat(order[ORDER_LOAD], "load"), part); + +		if (time_format) { +			/* Get date & time */ +			time_t current_time = time(NULL); +			struct tm *current_tm = localtime(¤t_time); +			strftime(part, sizeof(part), time_format, current_tm); +			write_to_statusbar(concat(order[ORDER_TIME], "time"), part); +		}  		sleep(1);  	} diff --git a/wmiistatus.h b/wmiistatus.h index e9d4445..e026e64 100644 --- a/wmiistatus.h +++ b/wmiistatus.h @@ -2,13 +2,17 @@  typedef enum { CS_DISCHARGING, CS_CHARGING, CS_FULL } charging_status_t; +#ifdef _IS_WMIISTATUS_C +static char *concat(const char *str1, const char *str2);  static void cleanup_rbar_dir(void);  static void write_to_statusbar(const char *name, const char *message);  static void write_error_to_statusbar(const char *message); -static void die(const char *fmt, ...);  static char *skip_character(char *input, char character, int amount);  static char *get_battery_info(void);  static char *get_wireless_info(void);  static char *get_ip_address(const char *interface);  static char *get_eth_info(void);  static bool process_runs(const char *path); +#endif + +void die(const char *fmt, ...); | 
