text: #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <unistd.h>
  #include <signal.h>
  #include <X11/Xlib.h>
  #ifdef __OpenBSD__
  #define SIGPLUS SIGUSR1 + 1
  #define SIGMINUS SIGUSR1 - 1
  #else
  #define SIGPLUS SIGRTMIN
  #define SIGMINUS SIGRTMIN
  #endif
  #define LENGTH(X) (sizeof(X) / sizeof(X[0]))
  #define CMDLENGTH 100
  #define MIN(a, b) ((a < b) ? a : b)
  #define STATUSLENGTH (LENGTH(blocks) * CMDLENGTH + 1)
  
  typedef struct {
  	char *icon;
  	char *command;
  	unsigned int interval;
  	unsigned int signal;
  } Block;
  #ifndef __OpenBSD__
  void dummysighandler(int num);
  #endif
  void sighandler(int num);
  void getcmds(int time);
  void getsigcmds(unsigned int signal);
  void setupsignals();
  void sighandler(int signum);
  int getstatus(char *str, char *last);
  void setroot();
  void statusloop();
  void termhandler();
  
  
  #include "blocks.h"
  
  static Display *dpy;
  static int screen;
  static Window root;
  static char statusbar[LENGTH(blocks)][CMDLENGTH] = {0};
  static char statusstr[2][STATUSLENGTH];
  static int statusContinue = 1;
  static void (*writestatus)() = setroot;
  
  // opens process *cmd and stores output in *output
  void getcmd(const Block *block, char *output)
  {
  	strcpy(output, block->icon);
  	FILE *cmdf = popen(block->command, "r");
  	if (!cmdf)
  		return;
  	int i = strlen(block->icon);
  	fgets(output + i, CMDLENGTH - i - delimLen, cmdf);
  	i = strlen(output);
  	if (i == 0) // return if block and command output are both empty
  		return;
  	if (delim[0] != '\0') {
  		// only chop off newline if one is present at the end
  		i = output[i - 1] == '\n' ? i - 1 : i;
  		strncpy(output + i, delim, delimLen);
  	} else
  		output[i++] = '\0';
  	pclose(cmdf);
  }
  
  void getcmds(int time)
  {
  	const Block *current;
  	for (unsigned int i = 0; i < LENGTH(blocks); i++) {
  		current = blocks + i;
  		if ((current->interval != 0 && time % current->interval == 0)
  		    || time == -1)
  			getcmd(current, statusbar[i]);
  	}
  }
  
  void getsigcmds(unsigned int signal)
  {
  	const Block *current;
  	for (unsigned int i = 0; i < LENGTH(blocks); i++) {
  		current = blocks + i;
  		if (current->signal == signal)
  			getcmd(current, statusbar[i]);
  	}
  }
  
  void setupsignals()
  {
  #ifndef __OpenBSD__
  	/* initialize all real time signals with dummy handler */
  	for (int i = SIGRTMIN; i <= SIGRTMAX; i++)
  		signal(i, dummysighandler);
  #endif
  
  	for (unsigned int i = 0; i < LENGTH(blocks); i++) {
  		if (blocks[i].signal > 0)
  			signal(SIGMINUS + blocks[i].signal, sighandler);
  	}
  }
  
  int getstatus(char *str, char *last)
  {
  	strcpy(last, str);
  	str[0] = '\0';
  	for (unsigned int i = 0; i < LENGTH(blocks); i++)
  		strcat(str, statusbar[i]);
  	str[strlen(str) - strlen(delim)] = '\0';
  	return strcmp(str, last); // 0 if they are the same
  }
  
  void setroot()
  {
  	if (!getstatus(statusstr[0],
  		       statusstr[1])) // Only set root if text has changed.
  		return;
  	Display *d = XOpenDisplay(NULL);
  	if (d) {
  		dpy = d;
  	}
  	screen = DefaultScreen(dpy);
  	root = RootWindow(dpy, screen);
  	XStoreName(dpy, root, statusstr[0]);
  	XCloseDisplay(dpy);
  }
  
  void pstdout()
  {
  	if (!getstatus(statusstr[0],
  		       statusstr[1])) // Only write out if text has changed.
  		return;
  	printf("%s\n", statusstr[0]);
  	fflush(stdout);
  }
  
  
  void statusloop()
  {
  	setupsignals();
  	int i = 0;
  	getcmds(-1);
  	while (statusContinue) {
  		getcmds(i++);
  		writestatus();
  		sleep(1.0);
  	}
  }
  
  #ifndef __OpenBSD__
  /* this signal handler should do nothing */
  void dummysighandler(int signum)
  {
  	return;
  }
  #endif
  
  void sighandler(int signum)
  {
  	getsigcmds(signum - SIGPLUS);
  	writestatus();
  }
  
  void termhandler()
  {
  	statusContinue = 0;
  }
  
  int main(int argc, char **argv)
  {
  	for (int i = 0; i < argc; i++) // Handle command line arguments
  	{
  		if (!strcmp("-d", argv[i]))
  			strncpy(delim, argv[++i], delimLen);
  		else if (!strcmp("-p", argv[i]))
  			writestatus = pstdout;
  	}
  	delimLen = MIN(delimLen, strlen(delim));
  	delim[delimLen++] = '\0';
  	signal(SIGTERM, termhandler);
  	signal(SIGINT, termhandler);
  	statusloop();
  }
  