~andreafeletto/cstatus

f3d01191d123eced32d6643ef514d7293ca87da7 — Andrea Feletto 2 months ago cc277d7
major debloat

removed daemon stuff
xlib calls instead of system()
3 files changed, 32 insertions(+), 176 deletions(-)

M config.h
M config.mk
M cstatus.c
M config.h => config.h +5 -5
@@ 2,9 2,9 @@
#define SEP " | "

static Block blocks[] = {
    backlight,
    volume,
    battery,
    sclock,
    NULL
	backlight,
	volume,
	battery,
	sclock,
	NULL
};

M config.mk => config.mk +1 -1
@@ 6,4 6,4 @@ CC = cc

CPPFLAGS = -D_POSIX_C_SOURCE=200112L
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${CPPFLAGS}
LDFLAGS = -lm
LDFLAGS = -lm -lX11

M cstatus.c => cstatus.c +26 -170
@@ 1,28 1,18 @@

#include <pwd.h>
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "utils.h"

#define VERSION "0.1.0"
#include <X11/Xlib.h>

static char *prgpath, *prgname;
static char prgdir[256], pidpath[256], logpath[256];
#include "utils.h"

static void usage(void);
static void refresh(void);
static void clean(void);
static pid_t getdaemonpid(void);
static void sendrefresh(void);
static void startdaemon(void);
static void stopdaemon(void);
static void signalhandler(int signum);
static Display *dpy;
static int screen;
static Window root;

typedef void (*Block)(char *);



@@ 31,191 21,57 @@ typedef void (*Block)(char *);
#include "config.h"

void
usage() {
	fprintf(stderr, "usage: %s OPTION\n"
		"statusbar for dwm.\n\n"
		"options:\n"
		"\t-h    display this help and exit\n"
		"\t-v    output version information\n"
		"\t-r    refresh\n"
		"\t-d    start in the background\n"
		"\t-s    stop daemon if one exists\n\n"
		"git repository: <https://git.sr.ht/~andreafeletto/cstatus>\n",
		prgname);
usage(void) {
	fprintf(stderr, "usage: cstatus\n\nstatusbar for dwm.\n");
	exit(EXIT_SUCCESS);
}

void
refresh(void) {
	FILE *fp;
	Block *b;
	char command[256] = "xsetroot -name \"";

	if ((fp = fopen(pidpath, "w")) == NULL) {
		die("error: cannot write pid");
	}
	fprintf(fp, "%d", getpid());
	fclose(fp);
	char name[256];

	name[0] = '\0';
	for (b = blocks; *b != NULL; b++) {
		strcat(command, SEP);
		(*b)(command);
	}
	strcat(command, "\"");

	if (system(NULL) == 0) {
		die("error: cannot spawn shell");
	}
	system(command);
}

void
clean(void) {
	if (access(pidpath, F_OK) != -1) {
		remove(pidpath);
		strcat(name, SEP);
		(*b)(name);
	}
	if (access(logpath, F_OK) != -1) {
		remove(logpath);
	}
	remove(prgdir);
	exit(EXIT_SUCCESS);
}

pid_t
getdaemonpid(void) {
	FILE *fp;
	pid_t pid;

	if ((fp = fopen(pidpath, "r")) == NULL) {
		return -1;
	}
	fscanf(fp, "%d", &pid);
	fclose(fp);
	return pid;
}

void
sendrefresh(void) {
	pid_t pid;

	if ((pid = getdaemonpid()) == -1) {
		die("error: no daemon running");
	}
	kill(pid, SIGUSR1);
	exit(EXIT_SUCCESS);
}

void
startdaemon(void) {
	pid_t pid;
	char command[256];

	pid = getdaemonpid();
	if (pid > 0 && kill(pid, 0) == 0) {
		die("error: daemon already running");
	}
	if (!system(NULL)) {
		die("error: no available shell");
	}

	sprintf(command, "%s >> \"%s\" 2>&1 &", prgpath, logpath);
	system(command);
	exit(EXIT_SUCCESS);
}

void
stopdaemon(void) {
	if (kill(getdaemonpid(), SIGTERM) < 0) {
		die("error: cannot kill daemon");
	}
	exit(EXIT_SUCCESS);
	XStoreName(dpy, root, name);
	XFlush(dpy);
}

void
signalhandler(int signum) {
	switch (signum) {
	case SIGUSR1:
		refresh();
		break;
	case SIGINT:
	case SIGTERM:
		clean();
		break;
	}
	assert(signum == SIGUSR1);

	refresh();
}

int
main (int argc, char **argv) {
	char *xdgdata, *homedir;
	struct sigaction sa;

	//
	// executable path and name
	//
	prgpath = argv[0];
	if ((prgname = strrchr(prgpath, '/')) == NULL) {
		prgname = prgpath;
	} else {
		prgname++;
	if (argc > 1) {
		usage();
	}

	//
	// program directory
	//
	if ((xdgdata = getenv("XDG_DATA_HOME")) != NULL) {
		sprintf(prgdir, "%s/%s", xdgdata, prgname);
	} else {
		if ((homedir = getenv("HOME")) == NULL) {
		    homedir = getpwuid(getuid())->pw_dir;
		}
		sprintf(prgdir, "%s/.local/share/%s", homedir, prgname);
	}
	mkdir(prgdir, 0755);

	//
	// runtime files
	//
	sprintf(pidpath, "%s/%s.pid", prgdir, prgname);
	sprintf(logpath, "%s/%s.log", prgdir, prgname);

	//
	// argument parsing
	//
	if (argc > 2) {
		usage ();
	}
	if (argc == 2) {
		if (strcmp(argv[1], "-v") == 0) {
			die(VERSION);
		} else if (strcmp(argv[1], "-r") == 0) {
			sendrefresh();
		} else if (strcmp(argv[1], "-d") == 0) {
			startdaemon();
		} else if (strcmp(argv[1], "-s") == 0) {
			stopdaemon();
		} else {
			usage();
		}
	dpy = XOpenDisplay(NULL);
	if (dpy == NULL) {
		die("cannot open display");
	}
	screen = DefaultScreen(dpy);
	root = RootWindow(dpy, screen);

	//
	// signal handling
	//
	sa.sa_handler = signalhandler;
	if (sigaction(SIGUSR1, &sa, NULL) == -1) {
		die("error: cannot listen to signal USR1");
	}
	if (sigaction(SIGINT, &sa, NULL) == -1) {
		die("error: cannot listen to signal INT");
	}
	if (sigaction(SIGTERM, &sa, NULL) == -1) {
		die("error: cannot listen to signal TERM");
	}

	while (1) {
		refresh();
		sleep (10);
		sleep(10);
	}

	XCloseDisplay(dpy);
	return EXIT_SUCCESS;
}