about summary refs log tree commit diff
path: root/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'url.c')
-rw-r--r--url.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/url.c b/url.c
index 3f7f512..7da0968 100644
--- a/url.c
+++ b/url.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2020  C. McEnroe <june@causal.agency>
+/* Copyright (C) 2020  June McEnroe <june@causal.agency>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@ static const char *Pattern = {
 	"("
 	"cvs|"
 	"ftp|"
+	"gemini|"
 	"git|"
 	"gopher|"
 	"http|"
@@ -86,14 +87,19 @@ static void push(uint 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) {
 		url->nick = strdup(nick);
 		if (!url->nick) err(EX_OSERR, "strdup");
 	}
-	url->url = strndup(str, len);
-	if (!url->url) err(EX_OSERR, "strndup");
+	url->url = malloc(len + 1);
+	if (!url->url) err(EX_OSERR, "malloc");
+
+	char buf[1024];
+	snprintf(buf, sizeof(buf), "%.*s", (int)len, str);
+	styleStrip(url->url, len + 1, buf);
 }
 
 void urlScan(uint id, const char *nick, const char *mesg) {
@@ -117,6 +123,7 @@ static void urlOpen(const char *url) {
 	if (pid < 0) err(EX_OSERR, "fork");
 	if (pid) return;
 
+	setsid();
 	close(STDIN_FILENO);
 	dup2(utilPipe[1], STDOUT_FILENO);
 	dup2(utilPipe[1], STDERR_FILENO);
@@ -168,6 +175,7 @@ static void urlCopy(const char *url) {
 		return;
 	}
 
+	setsid();
 	dup2(rw[0], STDIN_FILENO);
 	dup2(utilPipe[1], STDOUT_FILENO);
 	dup2(utilPipe[1], STDERR_FILENO);
@@ -225,3 +233,47 @@ void urlCopyMatch(uint id, const char *str) {
 		}
 	}
 }
+
+static int writeString(FILE *file, const char *str) {
+	return (fwrite(str, strlen(str) + 1, 1, file) ? 0 : -1);
+}
+static ssize_t readString(FILE *file, char **buf, size_t *cap) {
+	ssize_t len = getdelim(buf, cap, '\0', file);
+	if (len < 0 && !feof(file)) err(EX_IOERR, "getdelim");
+	return len;
+}
+
+int urlSave(FILE *file) {
+	for (size_t i = 0; i < Cap; ++i) {
+		const struct URL *url = &ring.urls[(ring.len + i) % Cap];
+		if (!url->url) continue;
+		int error = 0
+			|| writeString(file, idNames[url->id])
+			|| writeString(file, (url->nick ?: ""))
+			|| writeString(file, url->url);
+		if (error) return error;
+	}
+	return writeString(file, "");
+}
+
+void urlLoad(FILE *file, size_t version) {
+	if (version < 5) return;
+	size_t cap = 0;
+	char *buf = NULL;
+	while (0 < readString(file, &buf, &cap) && buf[0]) {
+		struct URL *url = &ring.urls[ring.len++ % Cap];
+		free(url->nick);
+		free(url->url);
+		url->id = idFor(buf);
+		url->nick = NULL;
+		readString(file, &buf, &cap);
+		if (buf[0]) {
+			url->nick = strdup(buf);
+			if (!url->nick) err(EX_OSERR, "strdup");
+		}
+		readString(file, &buf, &cap);
+		url->url = strdup(buf);
+		if (!url->url) err(EX_OSERR, "strdup");
+	}
+	free(buf);
+}