From d73085eaa93a0217a679556f7a37a80421877b69 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Wed, 12 Feb 2020 00:48:43 -0500 Subject: [PATCH] Allow for arguments to open/copy utilities --- catgirl.1 | 4 ++++ chat.c | 4 ++-- chat.h | 18 ++++++++++++++++-- url.c | 40 ++++++++++++++++++++++++++-------------- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/catgirl.1 b/catgirl.1 index abb9dd7..7b0b308 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -53,6 +53,8 @@ The arguments are as follows: .It Fl C Ar util , Cm copy = Ar util Set the utility used by .Ic /copy . +Use more than once to add arguments to +.Ar util . The default is the first available of .Xr pbcopy 1 , .Xr wl-copy 1 , @@ -66,6 +68,8 @@ the nick color hash function. .It Fl O Ar util , Cm open = Ar util Set the utility used by .Ic /open . +Use more than once to add arguments to +.Ar util . The default is the first available of .Xr open 1 , .Xr xdg-open 1 . diff --git a/chat.c b/chat.c index 14a02cb..2c41d43 100644 --- a/chat.c +++ b/chat.c @@ -120,9 +120,9 @@ int main(int argc, char *argv[]) { while (0 < (opt = getopt_config(argc, argv, Opts, LongOpts, NULL))) { switch (opt) { break; case '!': insecure = true; - break; case 'C': urlCopyUtil = optarg; + break; case 'C': utilPush(&urlCopyUtil, optarg); break; case 'H': hashInit = strtoul(optarg, NULL, 0); - break; case 'O': urlOpenUtil = optarg; + break; case 'O': utilPush(&urlOpenUtil, optarg); break; case 'R': self.restricted = true; break; case 'a': sasl = true; self.plain = optarg; break; case 'c': cert = optarg; diff --git a/chat.h b/chat.h index 39be36e..4e9a230 100644 --- a/chat.h +++ b/chat.h @@ -194,8 +194,22 @@ void completeClear(size_t id); size_t completeID(const char *str); enum Color completeColor(size_t id, const char *str); -extern const char *urlOpenUtil; -extern const char *urlCopyUtil; +enum { UtilCap = 16 }; +struct Util { + size_t argc; + const char *argv[UtilCap]; +}; + +static inline void utilPush(struct Util *util, const char *arg) { + if (1 + util->argc < UtilCap) { + util->argv[util->argc++] = arg; + } else { + errx(EX_CONFIG, "too many utility arguments"); + } +} + +extern struct Util urlOpenUtil; +extern struct Util urlCopyUtil; void urlScan(size_t id, const char *nick, const char *mesg); void urlOpenCount(size_t id, size_t count); void urlOpenMatch(size_t id, const char *str); diff --git a/url.c b/url.c index 1ccc206..bf3d948 100644 --- a/url.c +++ b/url.c @@ -95,8 +95,11 @@ void urlScan(size_t id, const char *nick, const char *mesg) { } } -const char *urlOpenUtil; -static const char *OpenUtils[] = { "open", "xdg-open" }; +struct Util urlOpenUtil; +static const struct Util OpenUtils[] = { + { 1, { "open" } }, + { 1, { "xdg-open" } }, +}; static void urlOpen(const char *url) { pid_t pid = fork(); @@ -106,15 +109,19 @@ static void urlOpen(const char *url) { close(STDIN_FILENO); dup2(procPipe[1], STDOUT_FILENO); dup2(procPipe[1], STDERR_FILENO); - if (urlOpenUtil) { - execlp(urlOpenUtil, urlOpenUtil, url, NULL); - warn("%s", urlOpenUtil); + if (urlOpenUtil.argc) { + struct Util util = urlOpenUtil; + utilPush(&util, url); + execvp(util.argv[0], (char *const *)util.argv); + warn("%s", util.argv[0]); _exit(EX_CONFIG); } for (size_t i = 0; i < ARRAY_LEN(OpenUtils); ++i) { - execlp(OpenUtils[i], OpenUtils[i], url, NULL); + struct Util util = OpenUtils[i]; + utilPush(&util, url); + execvp(util.argv[0], (char *const *)util.argv); if (errno != ENOENT) { - warn("%s", OpenUtils[i]); + warn("%s", util.argv[0]); _exit(EX_CONFIG); } } @@ -122,8 +129,13 @@ static void urlOpen(const char *url) { _exit(EX_CONFIG); } -const char *urlCopyUtil; -static const char *CopyUtils[] = { "pbcopy", "wl-copy", "xclip", "xsel" }; +struct Util urlCopyUtil; +static const struct Util CopyUtils[] = { + { 1, { "pbcopy" } }, + { 1, { "wl-copy" } }, + { 3, { "xclip", "-selection", "clipboard" } }, + { 3, { "xsel", "-i", "-b" } }, +}; static void urlCopy(const char *url) { int rw[2]; @@ -147,15 +159,15 @@ static void urlCopy(const char *url) { dup2(procPipe[1], STDOUT_FILENO); dup2(procPipe[1], STDERR_FILENO); close(rw[0]); - if (urlCopyUtil) { - execlp(urlCopyUtil, urlCopyUtil, NULL); - warn("%s", urlCopyUtil); + if (urlCopyUtil.argc) { + execvp(urlCopyUtil.argv[0], (char *const *)urlCopyUtil.argv); + warn("%s", urlCopyUtil.argv[0]); _exit(EX_CONFIG); } for (size_t i = 0; i < ARRAY_LEN(CopyUtils); ++i) { - execlp(CopyUtils[i], CopyUtils[i], NULL); + execvp(CopyUtils[i].argv[0], (char *const *)CopyUtils[i].argv); if (errno != ENOENT) { - warn("%s", CopyUtils[i]); + warn("%s", CopyUtils[i].argv[0]); _exit(EX_CONFIG); } }