commit 154c3d32af887121dc5779607c3ddf784ee05893
parent f5f2ddb9fd5f8d8c93805614d9b56f0eddf04457
Author: Pollux <pollux@pollux.codes>
Date: Tue, 11 Feb 2025 23:30:44 -0600
feat: Add command line arguments
Signed-off-by: Pollux <pollux@pollux.codes>
Diffstat:
M | sopen.1 | | | 13 | +++++++++++-- |
M | sopen.c | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- |
2 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/sopen.1 b/sopen.1
@@ -2,11 +2,20 @@
.SH "NAME"
sopen \- A suckless resources opener
.SH "SYNOPSIS"
-.B sopen <url/file>
+.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 Joseph "Pollux" Hand.
-.SH "SEE ALSO"
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;
}
}