From c2742808daafcc89b2d721eda21e78407f209028 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sun, 11 Mar 2012 18:48:45 -0400 Subject: [PATCH] updates --- gopher.c | 276 ++++++++++++++++++++++++++++++++++++------------------- url.c | 49 ++++++++-- url.h | 8 +- 3 files changed, 229 insertions(+), 104 deletions(-) diff --git a/gopher.c b/gopher.c index 820fce6..9830526 100644 --- a/gopher.c +++ b/gopher.c @@ -4,10 +4,12 @@ #include -//#include "url.h" -#include "Connect.h" +#include "url.h" +#include "connection.h" #include +#include +#include /* * connect gopher.floodgap.com:70 @@ -24,7 +26,7 @@ enum { kConnected = 4 }; -Word StartUp(void) +Word StartUp(displayPtr fx) { word status; word flags = 0; @@ -32,7 +34,7 @@ Word StartUp(void) status = TCPIPStatus(); if (_toolErr) { - LoadOneTool(54,0x0200); + LoadOneTool(54, 0x0201); if (_toolErr) return -1; status = 0; @@ -49,17 +51,18 @@ Word StartUp(void) status = TCPIPGetConnectStatus(); if (!status) { - TCPIPConnect(NULL); + TCPIPConnect(fx); flags |= kConnected; } + return flags; } -void ShutDown(word flags) +void ShutDown(word flags, Boolean force, displayPtr fx) { if (flags & kConnected) { - TCPIPDisconnect(false, NULL); + TCPIPDisconnect(force, fx); if (_toolErr) return; } if (flags & kStarted) @@ -73,51 +76,200 @@ void ShutDown(word flags) } } -#if 0 + +int gopher_binary(Word ipid, FILE *file) +{ + // gopher binary support. + // format: raw data until eof. + Word rv = 0; + + for(;;) + { + static char buffer[512]; + rrBuff rb; + Word count; + + TCPIPPoll(); + rv = TCPIPReadTCP(ipid, 0, (Ref)buffer, 512, &rb); + + count = rb.rrBuffCount; + if (rv == 0 && count == 0) continue; + + if (rv && !count) break; + + if (!count) continue; + fwrite(buffer, count, 1, file); + + } + + return rv; +} + +int gopher_text(Word ipid, FILE *file) +{ + // text \r\n + // ... + // . \r\n + // any leading '.' must be doubled. + + enum { + kStateText = 0, + kStateCR, + kStateEOL, + kStateDot, + kStateDotCR, + kStateEOF + }; + + static char buffer[256]; + unsigned state = kStateEOL; + int rv = 0; + + // I have bad luck with ReadLineTCP. + while (state != kStateEOF) + { + static char buffer[512]; + rrBuff rb; + Word count; + Word i; + + TCPIPPoll(); + rv = TCPIPReadTCP(ipid, 0, (Ref)buffer, 512, &rb); + + count = rb.rrBuffCount; + if (rv == 0 && count == 0) continue; + + //fprintf(stderr, "rv = %x, count = %u\n", rv, rb.rrBuffCount); + + //if (rv == tcperrConClosing) rv = 0; + if (rv && !count) break; + if (!count) continue; + + // scan the buffer for a line. + for (i = 0; i < count; ++i) + { + char c = buffer[i]; + + if (c == '.') + { + if (state == kStateEOL) state = kStateDot; + else fputc(c, file); + continue; + } + if (c == '\r') + { + if (state == kStateDot) state = kStateDotCR; + else state = kStateCR; + continue; + } + if (c == '\n') + { + if (state == kStateCR) + { + state = kStateEOL; + fputc('\n', file); + } + else if (state == kStateDotCR) + { + state = kStateEOF; + break; + } + // otherwise, silently drop? + continue; + } + + { + state = kStateText; // reset if kStateDot. + // . and \r will be silently dropped + fputc(c, file); + } + } + } + if (state != kStateEOF) + fprintf(stderr, "warning: eof not detected\n"); + + return rv; +} + + void do_url(const char *url) { URLComponents components; - ConnectBuffer buffer; + Connection buffer; char *host; + char type; - if (ParseURL(url, strlen(url), &components)) + if (!ParseURL(url, strlen(url), &components)) { fprintf(stderr, "Invalid URL: %s\n", url); return; } - if (!url.host.length) + + if (!components.host.length) { fprintf(stderr, "No host\n"); return; } + + if (!components.portNumber) components.portNumber = 70; - host = malloc(url.host.length + 1); - URLComponentGetCString(url, &components, host, URLComponentHost); - ConnectInit(&buffer, myID); + host = malloc(components.host.length + 1); + URLComponentGetC(url, &components, URLComponentHost, host); + + ConnectionInit(&buffer, MMStartUp()); - - ConnectCString(&buffer, host, components.portNumber); - - if (components.path.length) - { - rv = TCPIPWriteTCP(buffer.ipid, - url + components.path.location, - components.path.length, - 0, 0); - } - rv = TCPIPWriteTCP(buffer.ipid, "\r\n", 2, 1, 0); - + ConnectionOpenC(&buffer, host, components.portNumber); while (!ConnectionPoll(&buffer)) ; - if (buffer.state == ConnectionStateError) + + if (buffer.state == kConnectionStateError) { - fprintf(stderr, "Unable to open host: %s:%u\n", host, components.portNumber); + fprintf(stderr, "Unable to open host: %s:%u\n", + host, + components.portNumber); free(host); return; } + // connected.... + // path is /[type][resource] + // where [type] is 1 char and the leading / is ignored. + + if (components.path.length <= 1) + { + // / or blank + type = '1'; // directory + } + else if (components.path.length == 2) + { + // / type + // invalid -- treat as / + type = 1; + } + else + { + type = url[components.path.location+1]; + TCPIPWriteTCP( + buffer.ipid, + url + components.path.location + 2, + components.path.length - 2, + 0, + 0); + } + // + TCPIPWriteTCP(buffer.ipid, "\r\n", 2, true, 0); + + // 5 and 9 are binary, 1 is dir, all others text. + + if (type == 1 || type == 9) + gopher_binary(buffer.ipid, stdout); + else + gopher_text(buffer.ipid, stdout); + + fflush(stdout); + ConnectionClose(&buffer); while (!ConnectionPoll(&buffer)) ; // wait for it to close. @@ -125,82 +277,22 @@ void do_url(const char *url) free (host); } -#endif + int main(int argc, char **argv) { - Handle h; - ConnectBuffer buffer; int i; - Word rv; Word flags; - // getopt for -b binary + flags = StartUp(NULL); -#if 0 for (i = 1; i < argc; ++i) { do_url(argv[i]); } -#endif - - flags = StartUp(); - fprintf(stdout, "flags: %u\n", flags); - - ConnectionInit(&buffer, MMStartUp()); - - rv = ConnectionOpen(&buffer, "\pgopher.floodgap.com", 70); - while (!rv) - { - rv = ConnectionPoll(&buffer); - } - if (buffer.state == ConnectStateConnected) - { - fprintf(stdout, "Connected!\n"); - } - - fprintf(stdout, "%x %x %x\n", rv, buffer.state, buffer.terr); - - rv = TCPIPWriteTCP(buffer.ipid, "\r\n", 2, 1, 0); - if (rv) - { - fprintf(stdout, "TCPIPWriteTCP: %x\n", rv); - } - - for(;;) - { - rrBuff rb; - //rlrBuff rb; - Handle h; - Word count; - - TCPIPPoll(); - rv = TCPIPReadTCP(buffer.ipid, 2, NULL, 4096, &rb); - - //rv = TCPIPReadLineTCP(buffer.ipid, "\p\r\n", 2, NULL, 4096, &rb); - - if (rv) break; - h = rb.rrBuffHandle; - count = rb.rrBuffCount; - - if (!h) continue; - - HLock(h); - fwrite(*h, count, 1, stdout); - fputs("", stdout); - DisposeHandle(h); - } - - - rv = ConnectionClose(&buffer); - while (!rv) - { - rv = ConnectionPoll(&buffer); - } - fprintf(stdout, "%x %x %x\n", rv, buffer.state, buffer.terr); - - ShutDown(flags); + ShutDown(flags, false, NULL); + return 0; } diff --git a/url.c b/url.c index 5ce9eca..4b69cea 100644 --- a/url.c +++ b/url.c @@ -26,7 +26,7 @@ enum { * */ -int URLGetComponentCString(const char *url, struct URLComponents *components, int type, char *dest) +int URLComponentGetC(const char *url, URLComponents *components, int type, char *dest) { URLRange *rangePtr; URLRange r; @@ -53,6 +53,35 @@ int URLGetComponentCString(const char *url, struct URLComponents *components, in } } +// pstring. +int URLComponentGet(const char *url, URLComponents *components, int type, char *dest) +{ + URLRange *rangePtr; + URLRange r; + + if (!url || !components) return -1; + + + if (type < URLComponentScheme || type > URLComponentPathAndQuery) return -1; + + rangePtr = &components->scheme; + + r = rangePtr[type]; + + if (!dest) return r.length; + else if (r.length > 255) return -1; + else + { + dest[0] = r.length; + if (r.length) + { + memcpy(dest + 1, url + r.location, r.length); + } + + return r.length; + } +} + #if 0 int schemeType(const char *string) @@ -460,6 +489,8 @@ int ParseURL(const char *url, int length, struct URLComponents *components) } +#ifdef TEST + void test(const char *url) { URLComponents data; @@ -475,19 +506,19 @@ void test(const char *url) printf("%s (%s)\n", url, ok ? "ok" : "error"); - URLGetComponentCString(url, &data, URLComponentScheme, buffer); + URLComponentGetC(url, &data, URLComponentScheme, buffer); printf(" scheme: %s\n", buffer); - URLGetComponentCString(url, &data, URLComponentUser, buffer); + URLComponentGetC(url, &data, URLComponentUser, buffer); printf(" username: %s\n", buffer); - URLGetComponentCString(url, &data, URLComponentPassword, buffer); + URLComponentGetC(url, &data, URLComponentPassword, buffer); printf(" password: %s\n", buffer); - URLGetComponentCString(url, &data, URLComponentHost, buffer); + URLComponentGetC(url, &data, URLComponentHost, buffer); printf(" host: %s\n", buffer); - URLGetComponentCString(url, &data, URLComponentPort, buffer); + URLComponentGetC(url, &data, URLComponentPort, buffer); printf(" port: %s [%d]\n", buffer, data.portNumber); URLGetComponentCString(url, &data, URLComponentPath, buffer); @@ -496,10 +527,10 @@ void test(const char *url) URLGetComponentCString(url, &data, URLComponentParams, buffer); printf(" params: %s\n", buffer); - URLGetComponentCString(url, &data, URLComponentQuery, buffer); + URLComponentGetC(url, &data, URLComponentQuery, buffer); printf(" query: %s\n", buffer); - URLGetComponentCString(url, &data, URLComponentFragment, buffer); + URLComponentGetC(url, &data, URLComponentFragment, buffer); printf(" fragment: %s\n", buffer); free(buffer); @@ -517,3 +548,5 @@ int main(int argc, char **argv) return 0; } + +#endif diff --git a/url.h b/url.h index 81e2548..3150db2 100644 --- a/url.h +++ b/url.h @@ -53,11 +53,11 @@ typedef struct URLComponents { } URLComponents; -int ParseURL(const char *url, int length, struct URLComponents *components); +int ParseURL(const char *url, int length, URLComponents *components); -int URLGetComponentCString(const char *url, struct URLComponents *, int, char *); -int URLGetComponentPString(const char *url, struct URLComponents *, int, char *); -//int URLGetComponentGSString(const char *url, struct URLComponents *, int, GSString255Ptr); +int URLComponentGet(const char *url, URLComponents *, int, char *); +int URLComponentGetC(const char *url, URLComponents *, int, char *); +//int URLComponentGetGS(const char *url, URLComponents *, int, GSString255Ptr); #endif