~callum/gmsfn

2736f54758c4fd5306445edfe92e507cdade2046 — Callum Brown 1 year, 3 months ago ef6eb96
Improve logging and trust unknown certs once
1 files changed, 21 insertions(+), 16 deletions(-)

M src/gmsfn.c
M src/gmsfn.c => src/gmsfn.c +21 -16
@@ 13,7 13,7 @@ struct tofu_config {
	enum tofu_action action;
};

/* From gmni.c */
/* Adapted from gmni.c */
static enum tofu_action
tofu_callback(enum tofu_error error, const char *fingerprint,
	struct known_host *host, void *data)


@@ 35,8 35,10 @@ tofu_callback(enum tofu_error error, const char *fingerprint,
		fprintf(stderr,
			"The certificate offered by this server is of unknown trust. "
			"Its fingerprint is: \n"
			"%s\n\n"
			"Use -j once to trust temporarily, or -j always to add to the trust store.\n", fingerprint);
			"%s\n"
			"This certificate will be trusted once. Add it to your gemini "
			"known_hosts file to always trust it.\n",
			fingerprint);
		break;
	case TOFU_FINGERPRINT_MISMATCH:
		fprintf(stderr,


@@ 75,20 77,20 @@ bad_response(enum gemini_result r, struct gemini_response *resp)
{
	/* Check response */
	if (r != GEMINI_OK) {
		fprintf(stderr, "Error: %s\n", gemini_strerr(r, resp));
		fprintf(stderr, "Error: %s\n\n", gemini_strerr(r, resp));
		return true;
	}

	/* Check request was successful */
	if (gemini_response_class(resp->status) != GEMINI_STATUS_CLASS_SUCCESS) {
		fprintf(stderr, "Error: Unsuccessful request. Status: %d %s\n",
		fprintf(stderr, "Error: Unsuccessful request. Status: %d %s\n\n",
			resp->status, resp->meta);
		return true;
	}

	/* Check response is Gemtext */
	if (strncmp(resp->meta, "text/gemini", 11) != 0) {
		fprintf(stderr, "Error: Response is not text/gemini. Meta: %s\n",
		fprintf(stderr, "Error: Response is not text/gemini. Meta: %s\n\n",
			resp->meta);
		return true;
	}


@@ 166,12 168,12 @@ cat_and_rename(char *path1, char *path2)
{
	FILE *fp1 = fopen(path1, "a");
	if (!fp1) {
		fprintf(stderr, "Could not open %s for appending.\n", path1);
		fprintf(stderr, "Error: Could not open %s for appending.\n\n", path1);
		return 1;
	}
	FILE *fp2 = fopen(path2, "r");
	if (!fp2) {
		fprintf(stderr, "Could not open %s for reading.\n", path2);
		fprintf(stderr, "Error: Could not open %s for reading.\n\n", path2);
		return 1;
	}
	char buf[BUFSIZ];


@@ 181,10 183,10 @@ cat_and_rename(char *path1, char *path2)
	fclose(fp1);
	fclose(fp2);
	if (remove(path2) != 0) {
		fprintf(stderr, "Could not delete %s\n", path2);
		fprintf(stderr, "Error: Could not delete %s\n\n", path2);
	}
	if (rename(path1, path2) != 0) {
		fprintf(stderr, "Could not rename %s to %s\n", path1, path2);
		fprintf(stderr, "Error: Could not rename %s to %s\n\n", path1, path2);
		return 1;
	}
	return 0;


@@ 232,7 234,7 @@ main(int argc, char *argv[])
{
	/* Must have exactly one argument */
	if (argc != 2) {
		fprintf(stderr, "Usage: gmsfn /path/to/config/file.gmi");
		fprintf(stderr, "Usage: gmsfn /path/to/config/file.gmi\n");
		return 1;
	}



@@ 250,7 252,7 @@ main(int argc, char *argv[])
		.hints = &hints,
	};
	struct tofu_config cfg;
	cfg.action = TOFU_ASK;
	cfg.action = TOFU_TRUST_ONCE;
	SSL_load_error_strings();
	ERR_load_crypto_strings();
	opts.ssl_ctx = SSL_CTX_new(TLS_method());


@@ 298,7 300,8 @@ main(int argc, char *argv[])
				is bad. TODO: auto-create output files if needed. */
			FILE *count_fp = fopen(out_path, "r");
			if (!count_fp) {
				printf("Bad output file: %s\n", out_path);
				fprintf(stderr, "Error: Bad output file. Could not open %s for reading\n\n",
					out_path);
				/* Skip links until a new output file is given */
				good_output_file = false;
				continue;


@@ 349,13 352,14 @@ main(int argc, char *argv[])

			/* Make a temporary output file which new links will be written to.
				The existing output file will be appended to it before being
				deleted, then the temporary file will be renamed. (TODO)*/
				deleted, then the temporary file will be renamed. */
			tmp_out_path = malloc(strlen(out_path) + 5);
			strcpy(tmp_out_path, out_path);
			strcat(tmp_out_path, "-tmp");
			tmp_out_fp = fopen(tmp_out_path, "w");
			if (!tmp_out_fp) {
				fprintf(stderr, "Could not open temporary output file.");
				fprintf(stderr, "Error: Could not open %s for writing.\n\n",
					tmp_out_path);
				free(tmp_out_path);
				good_output_file = false;
			}


@@ 364,14 368,15 @@ main(int argc, char *argv[])
		/* Make requests and output links */
		} else if (good_output_file && token_is_good_link(config_tok)) {
			/* Get gemlog index page */
			fprintf(stderr, "Attempting request to %s\n", config_tok.link.url);
			struct gemini_response resp;
			enum gemini_result r = gemini_request(config_tok.link.url, &opts, &resp);
			if (bad_response(r, &resp)) {
				fprintf(stderr, "Could not access %s.\n", config_tok.link.url);
				gemini_response_finish(&resp);
				/* Go to next link in config file */
				continue;
			}
			fprintf(stderr, "Request successfull.\n\n");

			/* Parse gemlog index page */
			char *abs_url, *base_url = strip_filename(config_tok.link.url);