summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-02-08 19:04:25 -0500
committerJune McEnroe <june@causal.agency>2020-02-08 19:04:25 -0500
commit9b9794df33488acc82529ecb9cfe478441f5f48a (patch)
tree253ea4cddecdea6fc50151bc49675ff27a056a99
parentScan messages for URLs (diff)
downloadcatgirl-9b9794df33488acc82529ecb9cfe478441f5f48a.tar.gz
catgirl-9b9794df33488acc82529ecb9cfe478441f5f48a.zip
Implement URL opening
-rw-r--r--url.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/url.c b/url.c
index 7790461..1396765 100644
--- a/url.c
+++ b/url.c
@@ -14,12 +14,15 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+#include <assert.h>
 #include <err.h>
+#include <errno.h>
 #include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
+#include <unistd.h>
 
 #include "chat.h"
 
@@ -55,26 +58,31 @@ static void compile(void) {
 	errx(EX_SOFTWARE, "regcomp: %s: %s", buf, Pattern);
 }
 
+struct URL {
+	size_t id;
+	char *nick;
+	char *url;
+};
+
 enum { Cap = 32 };
 static struct {
-	size_t ids[Cap];
-	char *nicks[Cap];
-	char *urls[Cap];
+	struct URL urls[Cap];
 	size_t len;
 } ring;
+static_assert(!(Cap & (Cap - 1)), "Cap is power of two");
 
-static void push(size_t id, const char *nick, const char *url, size_t len) {
-	size_t i = ring.len++ % Cap;
-	free(ring.nicks[i]);
-	free(ring.urls[i]);
-	ring.ids[i] = id;
-	ring.nicks[i] = NULL;
+static void push(size_t id, const char *nick, const char *str, size_t len) {
+	struct URL *url = &ring.urls[ring.len++ % Cap];
+	free(url->nick);
+	free(url->url);
+	url->id = id;
+	url->nick = NULL;
 	if (nick) {
-		ring.nicks[i] = strdup(nick);
-		if (!ring.nicks[i]) err(EX_OSERR, "strdup");
+		url->nick = strdup(nick);
+		if (!url->nick) err(EX_OSERR, "strdup");
 	}
-	ring.urls[i] = strndup(url, len);
-	if (!ring.urls[i]) err(EX_OSERR, "strndup");
+	url->url = strndup(str, len);
+	if (!url->url) err(EX_OSERR, "strndup");
 }
 
 void urlScan(size_t id, const char *nick, const char *mesg) {
@@ -87,10 +95,45 @@ void urlScan(size_t id, const char *nick, const char *mesg) {
 	}
 }
 
+static const char *OpenBins[] = { "open", "xdg-open" };
+
+static void urlOpen(const char *url) {
+	pid_t pid = fork();
+	if (pid < 0) err(EX_OSERR, "fork");
+	if (pid) return;
+
+	close(STDIN_FILENO);
+	dup2(procPipe[1], STDOUT_FILENO);
+	dup2(procPipe[1], STDERR_FILENO);
+	for (size_t i = 0; i < ARRAY_LEN(OpenBins); ++i) {
+		execlp(OpenBins[i], OpenBins[i], url, NULL);
+		if (errno != ENOENT) {
+			warn("%s", OpenBins[i]);
+			_exit(EX_CONFIG);
+		}
+	}
+	warnx("no open utility found");
+	_exit(EX_CONFIG);
+}
+
 void urlOpenCount(size_t id, size_t count) {
-	// TODO
+	for (size_t i = 1; i <= Cap; ++i) {
+		const struct URL *url = &ring.urls[(ring.len - i) % Cap];
+		if (!url->url) break;
+		if (url->id != id) continue;
+		urlOpen(url->url);
+		if (!--count) break;
+	}
 }
 
 void urlOpenMatch(size_t id, const char *str) {
-	// TODO
+	for (size_t i = 1; i <= Cap; ++i) {
+		const struct URL *url = &ring.urls[(ring.len - i) % Cap];
+		if (!url->url) break;
+		if (url->id != id) continue;
+		if ((url->nick && !strcmp(url->nick, str)) || strstr(url->url, str)) {
+			urlOpen(url->url);
+			break;
+		}
+	}
 }
=1'>Move /opt/pkg after /usr in PATHJune McEnroe Installing mandoc from pkgsrc also installs a man executable which is horribly broken. Keep using the system man. 2019-02-20Set man_hard_wrap in nvimJune McEnroe Vendoring man.vim until <https://github.com/neovim/neovim/pull/9633> is merged and appears in a release. 2019-02-18Use hi -o anchor in upJune McEnroe 2019-02-18Don't match nested parentheses in Tag for CJune McEnroe Fixes mistaken highlight of: pngWrite(file, (uint8_t []) { 0, 0, 0 }, 3); 2019-02-18Match whitespace between * [] {}June McEnroe 2019-02-18Fix function-like #define regexJune McEnroe A define like #define FOO (1) is not function-like. 2019-02-18Match Tag in RustJune McEnroe 2019-02-18Match sh functions as TagJune McEnroe 2019-02-18Match Sh and Ss as Tag in mdocJune McEnroe 2019-02-18Match statics and typedefs as TagJune McEnroe 2019-02-18Clean up htmlHeaderJune McEnroe 2019-02-18Remove hi line numberingJune McEnroe Tags are much better for referring to specific parts of a file and line numbering is better done by a post-processing tool such as cat -n or producing a two-column HTML <table>. 2019-02-18Add Tag class to hiJune McEnroe 2019-02-17Generate HTML with hi -n -f html -o anchorJune McEnroe Running hi twice to insert stuff between the head and the content is a bit of a hack but oh well. 2019-02-17Add hi -f html -o anchor for line number linksJune McEnroe 2019-02-17Simplify temp trap in upJune McEnroe 2019-02-17Add line numbers to hiJune McEnroe Renames previous -n option to -m to stay consistent with cat -n. Prefixing lines with line numbers affects where the first tab indent ends up relative to the text above it. Not sure if it's worth fixing somehow. 2019-02-17Always split spans after newlinesJune McEnroe Simplifies ANSI and IRC output code, and prepares for line numbered output. 2019-02-15Color format specifiers light cyan in vimJune McEnroe 2019-02-15Highlight Interp as yellowJune McEnroe 2019-02-15Highlight strings in sh command substitutionsJune McEnroe 2019-02-15Add nmap gpJune McEnroe 2019-02-14Avoid newline when copying URL to pasteboardJune McEnroe 2019-02-13Add forgotten "sixth" book of H2G2June McEnroe