aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mstatus.1130
-rw-r--r--mstatus.c318
2 files changed, 0 insertions, 448 deletions
diff --git a/mstatus.1 b/mstatus.1
deleted file mode 100644
index 672dba1..0000000
--- a/mstatus.1
+++ /dev/null
@@ -1,130 +0,0 @@
-.\" vi: tw=80
-.\"
-.\" BSD Zero Clause License
-.\"
-.\" Copyright (c) 2022 Thomas Voss
-.\"
-.\" Permission to use, copy, modify, and/or distribute this software for any
-.\" purpose with or without fee is hereby granted.
-.\"
-.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-.\" AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-.\" OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-.\" PERFORMANCE OF THIS SOFTWARE.
-.Dd $Mdocdate: September 23 2022 $
-.Dt MSTATUS 1
-.Os
-.Sh NAME
-.Nm mstatus
-.Nd a modular status bar
-.Sh SYNOPSIS
-.Nm
-.Op Fl r
-.Op Fl s Ar seperator
-.Sh DESCRIPTION
-.Nm
-is a modular status bar.
-The
-.Nm
-status bar is comprised of a series of blocks which can be programmatically
-added, removed, and updated.
-These blocks appear side by side on the status bar seperated by the string
-.Dq " | " ,
-although this can be configured with the
-.Fl s
-flag.
-Commands are sent to and from the status bar via a named pipe located at
-.Pa $XDG_RUNTIME_DIR/mstatus.pipe
-or
-.Pa /run/user/$(id -u)/mstatus.pipe
-if the
-.Ev $XDG_RUNTIME_DIR
-environment variable is not set.
-.Ss SYNTAX
-The syntax used to send commands is extremely simple.
-Every command sent follows the form
-.Dq (\-?)([0-9]*)(.*)
-or in other words, an optional
-.Sq \-
-followed by an optional unsigned integer, followed by an optional string.
-Starting at the beginning, a leading
-.Sq \-
-tells
-.Nm
-that you would like to remove a block from the status bar.
-If the command does not begin with a
-.Sq \-
-then
-.Nm
-will attempt to create/update a block instead.
-.Pp
-Next, you can optionally provide a number which represents the block you want
-to act upon.
-As an example, the command
-.Dq \-10
-signals that you would like to remove block 10 from the status bar.
-The command
-.Dq 4
-on the other hand signals that you would like to create/update block 4.
-If no block number is specified, then the specified action will be executed on
-block 1.
-It is important to note that the command
-.Dq 0
-will be ignored as there is no block 0, however the command
-.Dq \-0
-is special in that it deletes all the blocks from the status bar.
-.Pp
-Finally, after you have provided the optional
-.Sq \-
-flag and have selected the block to act upon, you can provide any string which
-will be displayed in the selected block.
-If the
-.Sq \-
-flag was specified then this string will be simply ignored.
-.Sh OPTIONS
-.Bl -tag -width Ds
-.It Fl r
-Add a single space of padding to the right of the status bar.
-.It Fl s Ar seperator
-Set the block seperator to the string specified by
-.Ar seperator
-as opposed to the default of
-.Dq " | " .
-.El
-.Sh EXAMPLES
-Display the current time in block 1, and the current date in block 2:
-.Pp
-.Dl "$ date \(aq+%H:%M\(aq >$XDG_RUNTIME_DIR/mstatus.pipe # Note the implicit \(aq1\(aq"
-.Dl "$ date \(aq+2%d/%m/%Y\(aq >$XDG_RUNTIME_DIR/mstatus.pipe # Note the leading \(aq2\(aq"
-.Pp
-Delete the 5th block:
-.Pp
-.Dl $ echo \(aq-5\(aq >$XDG_RUNTIME_DIR/mstatus.pipe
-.Pp
-Replace the entire status bar with
-.Dq Hello world! :
-.Pp
-.Dl $ printf \(aq-0\enHello world!\(aq >$XDG_RUNTIME_DIR/mstatus.pipe
-.Sh EXIT STATUS
-.Ex -std
-.Sh NOTES
-.Nm
-always allocates enough memory to be able to hold as many blocks as the number
-of the rightmost block.
-This means that if you created a block in slots 1 and 2, memory will be
-allocated for 2 blocks, however if you create a block in slots 1, 2, and 300,
-then memory will be allocated for 300 blocks.
-It is for this reason that you should avoid creating blocks in very high slots
-without reason.
-Luckily if deleting the block in slot 300 from the above example, the memory
-for slots 3 to 300 will all be freed.
-.Sh BUGS
-As of the initial 1.0 version you cannot have a block which begins with a digit.
-.Sh SEE ALSO
-.Xr dwm 1 ,
-.Xr sway 1
-.Sh AUTHORS
-.An Thomas Voss Aq Mt thomasvoss@live.com
diff --git a/mstatus.c b/mstatus.c
deleted file mode 100644
index 9e68eb3..0000000
--- a/mstatus.c
+++ /dev/null
@@ -1,318 +0,0 @@
-#define _GNU_SOURCE
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <linux/limits.h>
-#include <paths.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdnoreturn.h>
-#include <signal.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#ifdef HAS_DWM
- #include <X11/Xlib.h>
-#endif
-
-#define CTOI(x) ((x) ^ 48)
-
-struct Block {
- int pos;
- char *text;
- bool remove;
-};
-
-bool rflag;
-const char *argv0;
-struct {
- char *str;
- size_t len;
-} seperator = {.str = " | ", .len = 3};
-
-static noreturn void usage(void);
-static noreturn void die(const char *);
-static void *xrealloc(void *, size_t);
-static void xfree(char **);
-static void write_status(struct Block);
-static bool process(char *, struct Block *);
-static void create_fifo(char *);
-
-#ifdef HAS_DWM
-static void daemonize(void);
-static void xfork(void);
-#endif
-
-void
-usage(void)
-{
- fprintf(stderr, "Usage: %s [-r] [-s seperator]\n", argv0);
- exit(EXIT_FAILURE);
-}
-
-void
-die(const char *s)
-{
- char *err = strerror(errno);
- syslog(LOG_ERR, "%s: %s", s, err);
- fprintf(stderr, "%s: %s: %s\n", argv0, s, err);
- exit(EXIT_FAILURE);
-}
-
-#ifdef HAS_DWM
-void
-xfork(void)
-{
- pid_t pid = fork();
- if (pid == -1)
- die("fork");
- if (pid != 0)
- exit(EXIT_SUCCESS);
-}
-#endif
-
-void *
-xrealloc(void *ptr, size_t size)
-{
- void *ret;
- if (!(ret = realloc(ptr, size)))
- die("realloc");
- return ret;
-}
-
-void
-xfree(char **ptr)
-{
- free(*ptr);
- *ptr = NULL;
-}
-
-void
-write_status(struct Block b)
-{
- static struct {
- char **blocks;
- int count;
- size_t length;
- } sb;
-
- if (b.remove) {
- if (b.pos > sb.count)
- return;
-
- /* b.remove && !b.pos is a special case to remove everything from the bar */
- if (!b.pos) {
- for (int i = 0; i < sb.count; i++)
- free(sb.blocks[i]);
- sb.count = 0;
- sb.blocks = xrealloc(sb.blocks, sizeof(char *));
- goto update_bar;
- }
-
- /* If the block is not NULL we free it */
- if (sb.blocks[--b.pos]) {
- sb.length -= strlen(sb.blocks[b.pos]);
- xfree(&sb.blocks[b.pos]);
- }
-
- /* If the block is the last one, we resize the bar to remove trailing NULL blocks */
- if (b.pos + 1 == sb.count) {
- for (; !sb.blocks[b.pos] && b.pos; b.pos--)
- sb.count--;
- sb.blocks = xrealloc(sb.blocks, sizeof(char *) * ++b.pos);
- }
- goto update_bar;
- }
-
- /* If the position exceeds the space allocated, allocate more blocks */
- if (b.pos > sb.count) {
- sb.blocks = xrealloc(sb.blocks, sizeof(char *) * b.pos);
- /* Make sure to set all the newly allocated blocks to NULL */
- for (int i = sb.count; i < b.pos; i++)
- sb.blocks[i] = NULL;
- sb.count = b.pos;
- }
-
- /* If the block is NULL we dont need to bother with strlen and free */
- if (sb.blocks[--b.pos]) {
- sb.length -= strlen(sb.blocks[b.pos]);
- xfree(&sb.blocks[b.pos]);
- }
- if (!(sb.blocks[b.pos] = strdup(b.text)))
- die("strdup");
- sb.length += strlen(b.text);
-
- /* The buffer to store the text that will be displayed in. It needs space for the text, the
- * seperators between the different blocks, the NUL byte at the end, and the right padding
- * space.
- */
-update_bar:;
- char buf[sb.length + (sb.count - 1) * seperator.len + 2];
- memset(buf, '\0', sizeof(buf));
-
- /* Double loops so that the seperator isnt printed to the left of the first block */
- int i;
- char *bufptr = buf;
- for (i = 0; i < sb.count; i++) {
- if (sb.blocks[i]) {
- bufptr = stpcpy(buf, sb.blocks[i]);
- break;
- }
- }
- while (++i < sb.count) {
- if (sb.blocks[i])
- bufptr = stpcpy(stpcpy(bufptr, seperator.str), sb.blocks[i]);
- }
- if (rflag)
- strcat(buf, " ");
-
-#ifdef HAS_DWM
- /* Xlib magic to set the DWM status */
- Display *dpy = XOpenDisplay(NULL);
- int screen = DefaultScreen(dpy);
- Window root = RootWindow(dpy, screen);
- (void) XStoreName(dpy, root, buf);
- (void) XCloseDisplay(dpy);
-#else
- puts(buf);
-#endif
-}
-
-bool
-process(char *line, struct Block *b)
-{
- if (*line == '-') {
- b->remove = true;
- line++;
- } else
- b->remove = false;
-
- if (!isdigit(*line))
- b->pos = 1; /* Default position */
- else {
- b->pos = 0;
- while (isdigit(*line))
- b->pos = b->pos * 10 + CTOI(*line++);
- if (!b->pos && !b->remove)
- return false;
- }
-
- b->text = line;
- return true;
-}
-
-void
-create_fifo(char *fifo_path)
-{
- char *runtime_dir = getenv("XDG_RUNTIME_DIR");
- if (runtime_dir) {
- size_t end = strlen(runtime_dir) - 1;
- if (runtime_dir[end] == '/')
- runtime_dir[end] = '\0';
- sprintf(fifo_path, "%s/%s.pipe", runtime_dir, argv0);
- } else
- sprintf(fifo_path, _PATH_VARRUN "user/%d/%s.pipe", getuid(), argv0);
-
- umask(0);
-
-create_fifo:
- if (mkfifo(fifo_path, DEFFILEMODE) == -1) {
- if (errno == EEXIST) {
- if (unlink(fifo_path) == -1)
- die("unlink");
- goto create_fifo;
- } else
- die("mkfifo");
- }
-
- syslog(LOG_INFO, "Created input FIFO '%s'", fifo_path);
-}
-
-#ifdef HAS_DWM
-void
-daemonize(void)
-{
- xfork();
- if (setsid() == -1)
- die("setsid");
-
- (void) signal(SIGCHLD, SIG_IGN);
- xfork();
-
- (void) chdir("/");
- (void) close(STDIN_FILENO);
- (void) close(STDOUT_FILENO);
- (void) close(STDERR_FILENO);
-
- stdin = fopen(_PATH_DEVNULL, "r");
- stdout = fopen(_PATH_DEVNULL, "w+");
- stderr = fopen(_PATH_DEVNULL, "w+");
-
- syslog(LOG_INFO, "Daemonized '%s'", argv0);
-}
-#endif
-
-int
-main(int argc, char **argv)
-{
- argv0 = argv[0];
-
- int opt;
- while ((opt = getopt(argc, argv, ":rs:")) != -1) {
- switch (opt) {
- case 'r':
- rflag = true;
- break;
- case 's':
- seperator.str = optarg;
- seperator.len = strlen(optarg);
- break;
- default:
- usage();
- }
- }
-
- openlog(argv0, LOG_PID | LOG_CONS,
-#ifdef HAS_DWM
- LOG_DAEMON
-#else
- LOG_USER
-#endif
- );
- char fifo_path[PATH_MAX];
- create_fifo(fifo_path);
-#ifdef HAS_DWM
- daemonize();
-#endif
-
- char *line = NULL;
- size_t len = 0;
- while (true) {
- FILE *fp;
- if (!(fp = fopen(fifo_path, "r")))
- die("fopen");
-
- ssize_t nr;
- while ((nr = getline(&line, &len, fp)) != -1) {
- /* For some reason output with newlines can cause performance issues */
- if (line[--nr] == '\n')
- line[nr] = '\0';
-
- syslog(LOG_DEBUG, "Recieved command '%s'", line);
-
- struct Block b;
- if (!process(line, &b))
- continue;
- write_status(b);
- }
- if (ferror(fp))
- die("getline");
-
- (void) fclose(fp);
- }
- /* NOTREACHED */
-}