summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--buf.c18
-rw-r--r--buf.h13
-rw-r--r--doc.h10
-rw-r--r--main.c19
-rw-r--r--nav.c42
-rw-r--r--nav.h8
-rw-r--r--net.c44
-rw-r--r--net.h14
8 files changed, 124 insertions, 44 deletions
diff --git a/buf.c b/buf.c
index dd93116..1f0e2b3 100644
--- a/buf.c
+++ b/buf.c
@@ -1,8 +1,9 @@
 #include <stdlib.h>
+#include <string.h>
 #include "buf.h"
 #include "err.h"
 
-void buf_init(struct buf *b, size_t n) {
+void buf_init(buf_t *b, size_t n) {
 	b->buf = calloc(1, n);
 	if (!b->buf) {
 		efatal("buf_init");
@@ -11,7 +12,7 @@ void buf_init(struct buf *b, size_t n) {
 	b->sz = 0;
 }
 
-void buf_grow(struct buf *b, size_t n) {
+void buf_grow(buf_t *b, size_t n) {
 	size_t sz = b->sz + n;
 	size_t c = b->cap;
 	if (sz > c) {
@@ -23,6 +24,17 @@ void buf_grow(struct buf *b, size_t n) {
 	}
 }
 
-void buf_free(struct buf *b) {
+void buf_cat(buf_t *b, char *src, size_t n) {
+	buf_grow(b, n);
+	memcpy(&b->buf[b->sz], src, n);
+	b->sz += n;
+}
+
+void buf_catc(buf_t *b, char c) {
+	buf_grow(b, 1);
+	b->buf[b->sz++] = c;
+}
+
+void buf_free(buf_t *b) {
 	free(b->buf);
 }
diff --git a/buf.h b/buf.h
index fdf0c52..c275f9c 100644
--- a/buf.h
+++ b/buf.h
@@ -3,13 +3,16 @@
 
 #include <stddef.h>
 
-struct buf {
+typedef struct buf {
 	size_t sz, cap;
 	char *buf;
-};
+} buf_t;
 
-void buf_init(struct buf *, size_t);
-void buf_grow(struct buf *, size_t);
-void buf_free(struct buf *);
+void buf_init(buf_t *, size_t);
+void buf_grow(buf_t *, size_t);
+void buf_free(buf_t *);
+
+void buf_cat(buf_t *b, char *src, size_t n);
+void buf_catc(buf_t *b, char c);
 
 #endif
diff --git a/doc.h b/doc.h
index 5e9c18c..fccd676 100644
--- a/doc.h
+++ b/doc.h
@@ -2,13 +2,7 @@
 #define DOC_H
 
 #include "buf.h"
-
-enum doc_type {
-	TYPE_UNKNOWN,
-	TYPE_GOPHERDOC,
-	TYPE_GEMTEXT,
-	TYPE_PLAIN,
-};
+#include "net.h"
 
 #define DOC_LINK_NONE 0xffff
 
@@ -18,7 +12,7 @@ struct doc_line {
 };
 
 struct doc {
-	struct buf txt, lnk;
+	buf_t txt, lnk;
 	size_t latest;
 };
 
diff --git a/main.c b/main.c
index 64343bc..0c36a34 100644
--- a/main.c
+++ b/main.c
@@ -5,7 +5,6 @@
 #include <stdlib.h>
 
 #include "doc.h"
-#include "net.h"
 #include "err.h"
 #include "nav.h"
 
@@ -13,20 +12,6 @@
 
 /* navigation */
 
-int nav_to(const char *url) {
-	struct addr a;
-	static enum protocol prot_default = PROT_FILE; /* change to gopher later */
-	if (net_addr(url, &a, prot_default)) {
-		return -1;
-	}
-	prot_default = a.prot;
-	return 0;
-}
-
-int nav_link_nr(unsigned long link_nr) {
-	return 0;
-}
-
 /* commands */
 
 struct cmd {
@@ -48,7 +33,7 @@ int cmd_do(char *cmd, struct nav_state *ns) {
 			unsigned long n = strtoul(cmd, NULL, 10);
 			if (errno) {
 				perr("invalid link number");
-			} else if (nav_link_nr(n)) {
+			} else if (nav_link_nr(ns, n)) {
 				perr("navigation failure");
 			}
 		}
@@ -63,7 +48,7 @@ int cmd_do(char *cmd, struct nav_state *ns) {
 		nav_redraw(ns);
 		break;
 	case 'g':
-		if (nav_to(cmd + 1)) perr("navigation failure");
+		if (nav_to(ns, cmd + 1)) perr("navigation failure");
 		break;
 	default:
 		perr("?");
diff --git a/nav.c b/nav.c
index 82cf71a..3a1d095 100644
--- a/nav.c
+++ b/nav.c
@@ -1,12 +1,17 @@
 #include <string.h>
 #include <stdio.h>
+
 #include "nav.h"
+#include "net.h"
+
+/* history */
 
 void nav_init(struct nav_state *ns) {
 	memset(ns, 0, sizeof *ns);
 	ns->histc = 1;
-	doc_init(&ns->histv[0]);
-	doc_add_text(&ns->histv[0], "Type ? for command help.");
+	doc_init(ns->histv);
+	doc_add_text(ns->histv, "Type ? for command help.");
+	ns->prot_default = PROT_FILE; /* change to PROT_GOPHER later */
 }
 
 void nav_fini(struct nav_state *ns) {
@@ -15,6 +20,16 @@ void nav_fini(struct nav_state *ns) {
 	}
 }
 
+void nav_new(struct nav_state *ns) {
+	if (ns->histc == HIST_MAX) {
+		doc_fini(ns->histv);
+		memmove(ns->histv, &ns->histv[1], sizeof(struct doc) * (HIST_MAX - 1));
+		ns->histc--;
+	}
+}
+
+/* paging */
+
 size_t pg_lines(void) {
 	return 24;
 }
@@ -59,4 +74,27 @@ void nav_pg_down(struct nav_state *ns) {
 }
 
 void nav_redraw(struct nav_state *ns) {
+	size_t lines = pg_lines();
+	while (lines-- && nav_line_up(ns));
+	nav_pg_down(ns);
+}
+
+/* network */
+
+int nav_to(struct nav_state *ns, const char *url) {
+	struct addr adr;
+	buf_t buf;
+	if (net_addr(url, &adr, ns->prot_default)) {
+		return -1;
+	}
+	ns->prot_default = adr.prot;
+	if (net_fetch(&adr, &buf)) {
+		return -1;
+	}
+	buf_free(&buf);
+	return 0;
+}
+
+int nav_link_nr(struct nav_state *ns, unsigned long link_nr) {
+	return 0;
 }
diff --git a/nav.h b/nav.h
index baefba9..69f666a 100644
--- a/nav.h
+++ b/nav.h
@@ -8,12 +8,20 @@ struct nav_state {
 	size_t histc, cur_doc;
 	struct doc histv[HIST_MAX];
 	size_t cur_ofs[HIST_MAX];
+	enum protocol prot_default;
 };
 
 void nav_init(struct nav_state *ns);
 void nav_fini(struct nav_state *ns);
+
+void nav_next(struct nav_state *ns);
+void nav_prev(struct nav_state *ns);
+
 void nav_pg_up(struct nav_state *ns);
 void nav_pg_down(struct nav_state *ns);
 void nav_redraw(struct nav_state *ns);
 
+int nav_to(struct nav_state *ns, const char *url);
+int nav_link_nr(struct nav_state *ns, unsigned long link_nr);
+
 #endif
diff --git a/net.c b/net.c
index 73f50d4..e90d3c0 100644
--- a/net.c
+++ b/net.c
@@ -1,5 +1,8 @@
 #include <string.h>
+#include <stdio.h>
+
 #include "net.h"
+#include "err.h"
 
 int net_addr(const char *url, struct addr *adr, enum protocol prot_default) {
 	char *prot_mark;
@@ -24,11 +27,40 @@ int net_addr(const char *url, struct addr *adr, enum protocol prot_default) {
 	} else {
 		adr->prot = prot_default;
 	}
-	adr->type = TYPE_PLAIN;
-	adr->host_len = 0;
-	size_t n = strlen(url);
-	if (n > PATH_MAX) return -1;
-	adr->path_len = n;
-	memcpy(adr->path, url, n);
+
+	if (adr->prot == PROT_FILE) {
+		adr->type = TYPE_PLAIN;
+		adr->host_len = 0;
+		size_t n = strlen(url);
+		if (n >= PATH_MAX) return -1;
+		adr->path_len = n;
+		memcpy(adr->path, url, n + 1);
+	} else {
+		return -1;
+	}
+
 	return 0;
 }
+
+int net_fetch(const struct addr *adr, struct buf *buf) {
+	switch (adr->prot) {
+	case PROT_FILE:
+		{
+			FILE *f = fopen(adr->path, "r/o");
+			if (!f) {
+				perr("file not found");
+				return -1;
+			}
+			buf_init(buf, 1024);
+			char b[256];
+			while (fgets(b, sizeof b, f)) {
+				buf_cat(buf, b, strlen(b));
+			}
+			buf_catc(buf, 0);
+			fclose(f);
+		}
+		return 0;
+	default:
+		return -1;
+	}
+}
diff --git a/net.h b/net.h
index 0b4422f..8483120 100644
--- a/net.h
+++ b/net.h
@@ -1,10 +1,10 @@
 #ifndef NET_H
 #define NET_H
 
-#include "doc.h"
+#include "buf.h"
 
-#define HOST_MAX 255
-#define PATH_MAX 255
+#define HOST_MAX 256
+#define PATH_MAX 256
 
 enum protocol {
 	PROT_UNKNOWN,
@@ -13,6 +13,13 @@ enum protocol {
 	PROT_GEMINI,
 };
 
+enum doc_type {
+	TYPE_UNKNOWN,
+	TYPE_GOPHERDOC,
+	TYPE_GEMTEXT,
+	TYPE_PLAIN,
+};
+
 struct addr {
 	char host[HOST_MAX];
 	char path[PATH_MAX];
@@ -22,5 +29,6 @@ struct addr {
 };
 
 int net_addr(const char *url, struct addr *adr, enum protocol prot_default);
+int net_fetch(const struct addr *adr, struct buf *buf);
 
 #endif