Make everything configurable
This commit is contained in:
parent
7c79d735d8
commit
a49ff50578
7
Makefile
7
Makefile
@ -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
|
||||
|
178
config.c
Normal file
178
config.c
Normal file
@ -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;
|
||||
}
|
39
config.h
39
config.h
@ -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
|
||||
|
90
wmiistatus.c
90
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);
|
||||
write_to_statusbar(concat(order[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);
|
||||
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);
|
||||
}
|
||||
|
@ -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, ...);
|
||||
|
Loading…
Reference in New Issue
Block a user