commit 023ea793d7f8276c8d80841f0362c34a6573225b
parent 8e1a3abd20fe784d91368edc1f53cd8dde8a75f2
Author: glenda <glenda@9front.local>
Date: Sun, 24 May 2020 17:04:59 +0000
uri parsing done, more or less
Diffstat:
M | gophra.c | | | 70 | +++++++++++++++++++++++++++++++++++++++++++++++++++++----------------- |
M | mkfile | | | 6 | ++++-- |
A | uri.c | | | 73 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | uri.h | | | 14 | ++++++++++++++ |
4 files changed, 144 insertions(+), 19 deletions(-)
diff --git a/gophra.c b/gophra.c
@@ -7,6 +7,8 @@
#include <keyboard.h>
#include <frame.h>
+#include "uri.h"
+
enum {
DBorder = DBlue,
DWBG = DBlack,
@@ -19,7 +21,7 @@ typedef struct Text Text;
struct Text {
char *data;
long size;
-} text;
+};
typedef struct History History;
struct History {
@@ -28,6 +30,8 @@ struct History {
History *prev;
};
+Text text;
+
History hzero, *hp;
Image *Iborder, *Iwbg, *Iwfg, *Iwfgl, *Istatus;
@@ -50,11 +54,12 @@ void drawtext(void);
void drawmenu(void);
int extracturl(char*);
char* getline(long);
-void handlelink(void);
+void handlelink(char*, char, char*);
int loadtext(char*, char*);
void runhold(void*);
void runpage(void*);
-int save(void);
+int save(char*, char*);
+int runuri(char*);
void
threadmain(int argc, char **argv)
@@ -95,17 +100,19 @@ threadmain(int argc, char **argv)
snprint(status, 255, "gophra!");
- if (argv[0] != 0) {
- strncpy(hzero.addr, argv[0], 256);
- loadtext(argv[0], "");
- }
-
calcrects();
drawborder();
drawstatus();
drawmenu();
flushimage(display, 1);
+ if (argc == 1) {
+ strncpy(hzero.addr, argv[0], 256);
+ runuri(argv[0]);
+ } else if (argc > 0) {
+ usage();
+ }
+
if((mc = initmouse(0, screen)) == nil)
sysfatal("initmouse failed: %r");
if((kc = initkeyboard(0)) == nil)
@@ -126,7 +133,7 @@ threadmain(int argc, char **argv)
char buf[256];
buf[0] = 0;
if (enter("goto:", buf, 255, mc, kc, 0) >=0)
- if (loadtext(buf, "") == 0){
+ if (runuri(buf) == 0){
drawmenu();
flushimage(display, 1);
}
@@ -166,7 +173,7 @@ threadmain(int argc, char **argv)
scroll;
s = getline(sline);
extracturl(s);
- handlelink();
+ handlelink(addr, type, path);
if (s != 0) free(s);
}
if (mv.buttons == 4) {
@@ -190,7 +197,7 @@ threadmain(int argc, char **argv)
void
usage(void)
{
- fprint(2, "usage: %s", argv0);
+ fprint(2, "usage: %s [gopher_uri]\n", argv0);
exits("usage");
}
@@ -356,13 +363,12 @@ extracturl(char *s)
}
void
-handlelink(void)
+handlelink(char *addr, char type, char *path)
{
History *hnew;
switch (type) {
case '0':
- save();
- proccreate(runhold, 0, 1024 * 8);
+ if (save(addr, path) == 0) proccreate(runhold, 0, 1024 * 8);
break;
case '1':
hnew = malloc(sizeof(History));
@@ -376,8 +382,7 @@ handlelink(void)
flushimage(display, 1);
break;
case 'I':
- save();
- proccreate(runpage, 0, 1024 * 8);
+ if (save(addr, path) == 0) proccreate(runpage, 0, 1024 * 8);
break;
default:
snprint(status, 255, "unknown type - %c", type);
@@ -433,8 +438,9 @@ runpage(void*)
procexecl(nil, "/bin/window", "window", "-m", "page", tmpfile, nil);
}
+
int
-save(void)
+save(char *addr, char *path)
{
int dcfd, wfd;
long n;
@@ -467,4 +473,34 @@ save(void)
drawstatus();
flushimage(display, 1);
return 0;
+}
+
+
+int
+runuri(char *s)
+{
+ URI *uri;
+ char *addr, *port, type, *path;
+ uri = chewuri(s);
+ if (uri == nil) {
+ snprint(status, 255, "invalid URI: %s", s);
+ return -1;
+ }
+ if (strcmp("gopher", uri->scheme) == 0){
+ port = (uri->port == nil) ? "gopher" : uri->port;
+ addr = netmkaddr(uri->host, "tcp", port);
+ type = '1';
+ path = "/";
+ if (strlen(uri->path) >=2) type = uri->path[1];
+ if (strlen(uri->path) > 2) path = uri->path + 2;
+ handlelink(addr, type, path);
+ } else {
+ snprint(status, 255, "Unknown scheme: %s", uri->scheme);
+ freeuri(uri);
+ free(uri);
+ return -1;
+ }
+ freeuri(uri);
+ free(uri);
+ return 0;
}
\ No newline at end of file
diff --git a/mkfile b/mkfile
@@ -1,8 +1,10 @@
</$objtype/mkfile
-BIN=/$objtype/bin
+# BIN=/$objtype/bin
+
+BIN=$home/bin/$objtype
TARG=gophra
-OFILES=gophra.$O
+OFILES=gophra.$O uri.$O
</sys/src/cmd/mkone
\ No newline at end of file
diff --git a/uri.c b/uri.c
@@ -0,0 +1,73 @@
+#include <u.h>
+#include <libc.h>
+#include <regexp.h>
+
+#include "uri.h"
+
+char*
+match2str(Resub *m)
+{
+ long n;
+ char *r;
+ if (m->sp == 0) return 0;
+ n = m->ep - m->sp + 1;
+ r = mallocz(n, 1);
+ strncpy(r, m->sp, n - 1);
+ return r;
+}
+
+URI*
+chewuri(char *s)
+{
+ URI *r;
+ Reprog *uriprog, *authprog;
+ Resub *m, *n;
+ char *auth;
+ auth = 0;
+ r = mallocz(sizeof(URI), 1);
+ m = mallocz(sizeof(Resub) * 16, 1);
+ n = mallocz(sizeof(Resub) * 8, 1);
+ /* scheme://user@host:port/path?query#fragment */
+
+ uriprog = regcomp(
+ "(([^:]+):)"
+ "(//([^/?#]+))?"
+ "(/?[^?#]*)?"
+ "(\\?([^#]+))?"
+ "(#(.*))?"
+ );
+ authprog = regcomp(
+ "(([^@]+)@)?"
+ "([^:]+)"
+ "(:([0-9]+))?"
+ );
+ if (regexec(uriprog, s, m, 16) == 1){
+ r->scheme = match2str(&m[2]);
+ auth = match2str(&m[4]);
+ r->path = match2str(&m[5]);
+ r->query = match2str(&m[7]);
+ r->fragment = match2str(&m[9]);
+ }
+ if ((auth != nil) && (regexec(authprog, auth, n, 8) == 1)) {
+ r->user = match2str(&n[2]);
+ r->host = match2str(&n[3]);
+ r->port = match2str(&n[5]);
+ }
+ free(uriprog);
+ free(authprog);
+ free(m);
+ free(n);
+ return r;
+}
+
+void
+freeuri(URI *uri)
+{
+ realloc(uri->scheme, 0);
+ realloc(uri->user, 0);
+ realloc(uri->host, 0);
+ realloc(uri->port, 0);
+ realloc(uri->path, 0);
+ realloc(uri->query, 0);
+ realloc(uri->fragment, 0);
+}
diff --git a/uri.h b/uri.h
@@ -0,0 +1,13 @@
+typedef struct URI URI;
+struct URI{
+ char *scheme;
+ char *user;
+ char *host;
+ char *port;
+ char *path;
+ char *query;
+ char *fragment;
+};
+
+URI* chewuri(char*);
+void freeuri(URI*);
+\ No newline at end of file