diff options
author | wrmr | 2024-11-03 02:48:05 -0500 |
---|---|---|
committer | wrmr | 2024-11-03 02:48:05 -0500 |
commit | 3e9c75318b0eb1114fb7361dbc467990674804b6 (patch) | |
tree | 504efbb2fe56c4700055ec584170cb77237c732a | |
parent | 610808a5902adad751a4acdbcc310803a51fed5d (diff) |
start working on fetching
-rw-r--r-- | buf.c | 18 | ||||
-rw-r--r-- | buf.h | 13 | ||||
-rw-r--r-- | doc.h | 10 | ||||
-rw-r--r-- | main.c | 19 | ||||
-rw-r--r-- | nav.c | 42 | ||||
-rw-r--r-- | nav.h | 8 | ||||
-rw-r--r-- | net.c | 44 | ||||
-rw-r--r-- | net.h | 14 |
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 |