richterm

"terminal emulator" with support for text fonts and images for plan9
git clone git://nsmpr.xyz/richterm.git
Log | Files | Refs | README

Gopher.c (2879B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 
      5 const char *scheme = "gopher://";
      6 char *rroot = "/mnt/richterm";
      7 
      8 void
      9 usage(void)
     10 {
     11 	fprint(2, "usage: %s [gopher_url]\n", argv0);
     12 	exits("usage");
     13 }
     14 
     15 void
     16 printtext(char *buf, long size)
     17 {
     18 	Biobuf* bd;
     19 	long n;
     20 	bd = Bfdopen(1, OWRITE);
     21 	Bprint(bd, "f\nl\n" ".");
     22 	for (n = 0; n < size; n++) {
     23 		if (buf[n] == '\r') continue;
     24 		else if (buf[n] == '\n') Bprint(bd, "\n" "n\n" ".");
     25 		else Bputc(bd, buf[n]);
     26 	}
     27 	Bprint(bd, "\n");
     28 }
     29 
     30 void
     31 printmenu(char *buf, long size)
     32 {
     33 	char *lbuf, *ls, *le, type, *port, *host, *path, url[1024];
     34 	long lsize, n;
     35 	int urlblank;
     36 
     37 	ls = buf;
     38 	lsize = 1024;
     39 	lbuf = malloc(lsize);
     40 	urlblank = 0;
     41 	while (ls < buf + size) {
     42 		le = strchr(ls, '\n');
     43 		if (le == nil) break;
     44 		n = le - ls;
     45 		if (lsize < n) {
     46 			lsize = n;
     47 			free(lbuf);
     48 			lbuf = malloc(lsize);
     49 		}
     50 		memcpy(lbuf, ls, n);
     51 		lbuf[n - 1] = '\0';
     52 		type = lbuf[0];
     53 		ls = le + 1;
     54 		if (type == '.') break;
     55 		le = strchr(lbuf, '\t');
     56 		if (le == nil) return; // sysfatal("gopher menu is malformed\n");
     57 		*le = '\0';
     58 		switch (type) {
     59 		case 'i':
     60 		case 'e':
     61 			url[0] = '\0';
     62 			break;
     63 		default:
     64 			path = le + 1;
     65 			le = strchr(path, '\t');
     66 			*le = '\0';
     67 			host = le + 1;
     68 			le = strchr(host, '\t');
     69 			*le = '\0';
     70 			port = le + 1;
     71 			snprint(url, 1024, "gopher://%s:%s/%c%s", host, port, type, path);
     72 		}
     73 
     74 		if (url[0] != '\0') {
     75 			print("l%s\n", url);
     76 			urlblank = 0;
     77 		} else if (urlblank == 0) {
     78 			print("l\n");
     79 			urlblank = 1;
     80 		}
     81 
     82 		if (lbuf[1] != '\0') {
     83 			print(".%s\n", lbuf + 1);
     84 		}
     85 
     86 		print("n\n");
     87 	}
     88 }
     89 
     90 void
     91 main(int argc, char **argv)
     92 {
     93 	char *url, *up, *host, *port, type, *path, *netaddr, *buf;
     94 	int fd;
     95 	long n, size;
     96 	void (*printfunc) (char *, long);
     97 	argv0 = argv[0];
     98 	printfunc = nil;
     99 	if ((argc == 1) || (argc > 2)) usage();
    100 	url = argv[1];
    101 	if (strncmp(scheme, url, strlen(scheme)) != 0) {
    102 		fprint(2, "%s: invalid url\n", url);
    103 		exits("invalid url");
    104 	}
    105 	type = '1';
    106 	path = "/";
    107 	port = "70";
    108 	url = url + strlen(scheme);
    109 	up = strchr(url, '/');
    110 	if (up != nil) {
    111 		host = mallocz(up - url + 1, 1);
    112 		memcpy(host, url, up - url);
    113 		up++;
    114 		if (up < url + strlen(url)) {
    115 			type = *(up);
    116 			path = ++up;
    117 		}
    118 		up = strchr(host, ':');
    119 		if (up != nil) {
    120 			*up = '\0';
    121 			port = up + 1;
    122 		}
    123 	} else {
    124 		host = url;
    125 	}
    126 	switch (type) {
    127 	case '0':
    128 		printfunc = printtext;
    129 		break;
    130 	case '1':
    131 		printfunc = printmenu;
    132 		break;
    133 	default:
    134 		sysfatal("unknown gopher type: %c\n", type);
    135 	}
    136 	netaddr = netmkaddr(host, "tcp", port);
    137 	fd = dial(netaddr, nil, nil, nil);
    138 	if (fd < 0) {
    139 		fprint(2, "url: %s\n", argv[1]);
    140 		fprint(2, "netaddr: %s\n", netaddr);
    141 		sysfatal("dial: %r");
    142 	}
    143 	write(fd, path, strlen(path));
    144 	write(fd, "\n", 1);
    145 	buf = malloc(4096);
    146 	size = 0;
    147 	while((n = read(fd, buf + size, 4096)) > 0) {
    148 		size += n;
    149 		buf = realloc(buf, size + 4096);
    150 	}
    151 	close(fd);
    152 	printfunc(buf, size);
    153 }