~callum/gmsfn

138deec3e71279b2b1ddd7cefb11baededf22a92 — Callum Brown 1 year, 3 months ago 11ea99f
Work out the absolute url for each link
1 files changed, 71 insertions(+), 2 deletions(-)

M src/gemlogger.c
M src/gemlogger.c => src/gemlogger.c +71 -2
@@ 60,8 60,71 @@ tofu_callback(enum tofu_error error, const char *fingerprint,
}


/* Return url up to and including the last '/' */
char *
get_url_without_filename(const char *url)
{
	size_t last_slash;
	for (size_t i = 0; i < strlen(url); ++i) {
		if (url[i] == '/')
			last_slash = ++i;
	}
	return strndup(url, last_slash);
}


/* Add scheme and domain to url if needed */
char *
get_absolute_url(char *url, char *base_url)
{
	bool not_absolute = false, colon = false, slash = false;
	size_t i = 0;
	while (i < strlen(url) && !(not_absolute)) {
		switch (url[i]) {
		case ':':
			if (i == 0 || colon) {
				/* If colon is first char then no scheme */
				/* 2 colons but no slashes means no scheme */
				not_absolute = true;
				break;
			} else {
				/* This is the first colon */
				colon = true;
				break;
			}
		case '/':
			if (colon && slash) {
				/* Last 2 chars were ":/" so url has scheme. Assuming there is
					a valid domain after, url is absolute. */
				return url;
			} else if (colon) {
				/* This slash directly follows a colon */
				slash = true;
				break;
			} else {
				/* This slash is before any colon, so no scheme */
				not_absolute = true;
				break;
			}
		default:
			/* If there has been a colon but this character is not a slash,
				then the url is not absolute. Break the loop. */
			if (colon)
				not_absolute = true;
		}
		++i;
	}
	/* remove leading slashes */
	while (*url && (*url == '/')) ++url;
	char *abs_url = malloc(strlen(base_url) + strlen(url) + 1);
	strcpy(abs_url, base_url);
	return strcat(abs_url, url);
}

int main() {

int
main()
{
	struct addrinfo hints = {0};
	struct gemini_options opts = {
		.hints = &hints,


@@ 77,7 140,7 @@ int main() {

	int ret = 0;
	// Random note: Does not follow redirects
	const char *url = "gemini://calcuode.com/";
	const char *url = "gemini://calcuode.com/index.gmi";
	struct gemini_response resp;
	enum gemini_result r = gemini_request(url, &opts, &resp);
	if (r != GEMINI_OK) {


@@ 101,6 164,9 @@ int main() {
		goto next;
	}

	char *base_url = get_url_without_filename(url);
	char *abs_url;

	struct gemini_parser p;
	gemini_parser_init(&p, resp.bio);
	FILE *out = stdout;


@@ 111,9 177,12 @@ int main() {
				// No url, ignore
				continue;
			}
			abs_url = get_absolute_url(tok.link.url, base_url);
			fprintf(out, "link text: %s\n", tok.link.text);
			fprintf(out, "link url: %s\n", tok.link.url);
			fprintf(out, "abs  url: %s\n", abs_url);
			fprintf(out, "\n");
			free(abs_url);
		}
	}
	gemini_token_finish(&tok);