commit 351848b8f321dc49706b2133e899cf46df5be5a6
parent 66bf65deca9ca42f31cd986412fbc96e83753030
Author: Pollux <pollux@pollux.codes>
Date: Tue, 11 Feb 2025 22:54:04 -0600
docs: Add man page
Signed-off-by: Pollux <pollux@pollux.codes>
Diffstat:
M | Makefile | | | 5 | ++++- |
A | sopen.1 | | | 21 | +++++++++++++++++++++ |
M | sopen.c | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
3 files changed, 97 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
@@ -2,6 +2,7 @@
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
+MANDIR ?= $(PREFIX)/share/man
BINSUFFIX ?=
PROGNAME = sopen
@@ -32,6 +33,8 @@ clean:
rm "$(PROGNAME)$(BINSUFFIX)"
install:
- install -d $(DESTDIR)$(BINDIR)/
+ install -d $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MANDIR)/man1/
install -s -m 755 "$(PROGNAME)$(BINSUFFIX)" \
$(DESTDIR)$(BINDIR)/$(PROGNAME)$(BINSUFFIX)
+ install -m 644 -D "$(PROGNAME).1" \
+ "$(DESTDIR)$(MANDIR)/man1/"
diff --git a/sopen.1 b/sopen.1
@@ -0,0 +1,21 @@
+.TH "sopen" 1
+.SH "NAME"
+sopen \- A suckless resources opener
+.SH "SYNOPSIS"
+.B sopen [-h] [-V] [-d] <url/file>
+.SH "DESCRIPTION"
+sopen is a minimal resource opener, like mime-open, that matches compile-time
+configured regular expressions against the url or file path provided and runs
+the desired program with the same url or path.
+.SH "OPTIONS"
+.TP
+.B \-d
+dry run (print command that would have been executed, but don't execute).
+.TP
+.B \-h
+print usage information to stdout, then exit.
+.TP
+.B \-V
+print version information to stdout, then exit.
+.SH "AUTHORS"
+sopen was written by Pollux.
diff --git a/sopen.c b/sopen.c
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
+#include <getopt.h>
#include <magic.h>
#include <regex.h>
#include <spawn.h>
@@ -13,6 +14,11 @@
#define REGEX_PROTOCOL "^[a-z]*://"
#define REGEX_URL "^(([a-z]*)://(.*)/)?(.*)$"
+#define USAGE "usage: sopen [-h] [-v] [-d] <url/file>"
+
+#define STR_LITERAL(x) #x
+#define STRINGIFY(x) STR_LITERAL(x)
+
typedef struct {
const char *protocol_regex;
const char *url_regex;
@@ -21,6 +27,10 @@ typedef struct {
const char *program;
} Rule;
+void print_help();
+void print_version();
+void parse_args(const int argc, char *const *argv, int *dry_run,
+ int *url_ind);
int parse_url(const char *url, char *protocol, char *file);
int match_rule(const Rule rule, const char *url,
const char *protocol, const char *file,
@@ -28,6 +38,50 @@ int match_rule(const Rule rule, const char *url,
#include "config.h"
+void
+print_help() {
+ printf(USAGE "\n");
+}
+
+void
+print_version() {
+ printf(STRINGIFY(PROGNAME) " " STRINGIFY(VERSION) "\n");
+ printf("CFLAGS: " STRINGIFY(CFLAGS) "\n");
+ printf("LDFLAGS: " STRINGIFY(LDFLAGS) "\n");
+}
+
+void
+parse_args(const int argc, char *const *argv, int *dry_run, int *url_ind) {
+
+ char *cvalue = NULL;
+ int index;
+ int c;
+
+ opterr = 0;
+
+ while((c = getopt(argc, argv, "dhV")) != -1) {
+ switch (c) {
+ case 'd':
+ *dry_run = 1;
+ break;
+ case 'h':
+ print_help();
+ exit(0);
+ case 'V':
+ print_version();
+ exit(0);
+ case '?':
+ fprintf(stderr,
+ "Unknown option `\\x%x'. Run `sopen -h' for usage.\n",
+ optopt);
+ exit(1);
+ default:
+ exit(255);
+ }
+ }
+ *url_ind = optind;
+}
+
int
parse_url(const char *url, char *protocol, char *file) {
@@ -61,6 +115,8 @@ match_rule(const Rule rule, const char *url, const char *protocol,
regex_t regex;
int res;
+ int dry_run = 0;
+
res = regcomp(®ex, rule.url_regex, REG_EXTENDED);
if(res > 0) {
printf("Failed to compile url regex: %s\n", rule.url_regex);
@@ -102,16 +158,19 @@ match_rule(const Rule rule, const char *url, const char *protocol,
}
int
-main(int argc, const char **argv) {
+main(int argc, char *const *argv) {
int res;
+ int dry_run;
+ int url_ind;
magic_t cookie;
regex_t has_protocol;
- const char *url;
const char *mime_type;
+
+ const char *url;
char protocol[16];
char file[1024];
@@ -124,7 +183,11 @@ main(int argc, const char **argv) {
}
magic_load(cookie, NULL);
- url = argv[1];
+ parse_args(argc, argv, &dry_run, &url_ind);
+ url = argv[url_ind];
+
+ printf("%s\n", url);
+ printf("%d\n", dry_run);
res = regcomp(&has_protocol, REGEX_PROTOCOL, REG_EXTENDED);
if(res > 0)
@@ -145,10 +208,15 @@ main(int argc, const char **argv) {
res = match_rule(rules[n], url, protocol, file, mime_type);
if(res == 0) {
+
child_args[0] = (char *)rules[n].program;
child_args[1] = (char *)url;
child_args[2] = NULL;
- execvp(rules[n].program, child_args);
+ if(dry_run) {
+ printf("%s %s\n", child_args[0], child_args[1]);
+ } else {
+ execvp(rules[n].program, child_args);
+ }
return 0;
}
}