jcs
/detritus
/amendments
/25
*: Split handler process into fetch and process, for downloading
jcs made amendment 25 about 1 year ago
--- browser.c Mon Nov 4 14:36:26 2024
+++ browser.c Wed Nov 6 12:52:48 2024
@@ -34,14 +34,14 @@
static Rect zerorect = { 0, 0, 0, 0 };
static Pattern fill_pattern;
+extern struct uri_handler finger_handler;
extern struct uri_handler gemini_handler;
extern struct uri_handler gopher_handler;
-extern struct uri_handler finger_handler;
struct uri_handler * uri_handlers[] = {
+ &finger_handler,
&gemini_handler,
&gopher_handler,
- &finger_handler,
};
bool browser_close(struct focusable *focusable);
@@ -68,17 +68,35 @@ browser_idle(struct focusable *focusable, EventRecord
{
struct browser *browser = (struct browser *)focusable->cookie;
struct uri_handler *handler;
+ struct page *page;
+ bool ret;
TEIdle(browser->uri_te);
- if (browser->loading_page) {
- HLock(browser->loading_page);
- handler = (*(browser->loading_page))->handler;
- HUnlock(browser->loading_page);
+ if (!browser->loading_page)
+ return;
- if (!handler->process(browser->loading_page))
- browser_finished_loading(browser);
+ HLock(browser->loading_page);
+ page = *(browser->loading_page);
+ handler = page->handler;
+
+ ret = true;
+ if (page->fetch_cookie != NULL || page->download_frefnum) {
+ ret = handler->fetch(page);
+
+ /* handle may have grown during fetch */
+ HLock(browser->loading_page);
+ page = *(browser->loading_page);
+ handler = page->handler;
}
+
+ if (!page->download_frefnum)
+ ret &= handler->process(page);
+
+ if (!ret)
+ browser_finished_loading(browser);
+
+ HUnlock(browser->loading_page);
}
struct browser *
@@ -234,27 +252,22 @@ browser_close(struct focusable *focusable)
browser_stop_loading_page(browser);
if (browser->current_page) {
- pageh = browser->current_page;
- HLock(pageh);
- fpage = (*pageh)->fwd_page;
- HUnlock(pageh);
+ fpage = (*(browser->current_page))->fwd_page;
while (fpage) {
HLock(fpage);
tpage = (*fpage)->fwd_page;
- (*fpage)->handler->cleanup(fpage);
+ (*fpage)->handler->cleanup(*fpage);
HLock(fpage);
xfree(&(*fpage)->uri);
DisposeHandle(fpage);
fpage = tpage;
}
- HLock(pageh);
bpage = (*pageh)->back_page;
- HUnlock(pageh);
while (bpage) {
HLock(bpage);
tpage = (*bpage)->back_page;
- (*bpage)->handler->cleanup(bpage);
+ (*bpage)->handler->cleanup(*bpage);
HLock(bpage);
xfree(&(*bpage)->uri);
DisposeHandle(bpage);
@@ -262,7 +275,7 @@ browser_close(struct focusable *focusable)
}
HLock(pageh);
- (*pageh)->handler->cleanup(pageh);
+ (*pageh)->handler->cleanup(*pageh);
HLock(pageh);
xfree(&(*pageh)->uri);
DisposeHandle(pageh);
@@ -285,36 +298,37 @@ void
browser_finished_loading(struct browser *browser)
{
struct URI *redir;
- struct page *page;
size_t size;
+ bool download = false;
- HLock(browser->loading_page);
-
if ((*(browser->loading_page))->redir_to) {
browser_follow_redir(browser);
- HUnlock(browser->loading_page);
return;
}
+ if ((*(browser->loading_page))->download_frefnum) {
+ FSClose((*(browser->loading_page))->download_frefnum);
+ browser_statusf(browser, "Finished downloading %ld bytes",
+ (*(browser->loading_page))->download_len);
+ download = true;
+ }
+
browser_stop_loading_page(browser);
browser->redirs = 0;
+ if (download)
+ return;
+
/* release some memory if we can */
- HLock(browser->current_page);
- page = *(browser->current_page);
- if (page->content_size > page->content_len) {
- size = page->content_len;
- page->content_size = size;
+ if ((*(browser->current_page))->content_size >
+ (*(browser->current_page))->content_len) {
+ size = (*(browser->current_page))->content_len;
+ (*(browser->current_page))->content_size = size;
HUnlock(browser->current_page);
SetHandleSize(browser->current_page, sizeof(struct page) + size);
- HLock(browser->current_page);
- page = *(browser->current_page);
}
-
- browser_statusf(page->browser, "Finished loading %ld bytes",
- page->content_len);
-
- HUnlock(browser->current_page);
+ browser_statusf(browser, "Finished loading %ld bytes",
+ (*(browser->current_page))->content_len);
}
void
@@ -328,12 +342,14 @@ browser_stop_loading_page(struct browser *browser)
HLock(browser->loading_page);
page = *(browser->loading_page);
- page->handler->cleanup(browser->loading_page);
- HLock(browser->loading_page);
+ page->handler->cleanup(page);
+ HUnlock(browser->loading_page);
+ if ((*(browser->loading_page))->download_frefnum)
+ FSClose((*(browser->loading_page))->download_frefnum);
+
/* only dispose if uncommitted */
if (browser->current_page != browser->loading_page) {
- HLock(browser->loading_page);
xfree(&(*(browser->loading_page))->uri);
DisposeHandle(browser->loading_page);
}
@@ -403,16 +419,12 @@ void
browser_update_menu(struct browser *browser)
{
size_t vlines;
- TERec *te;
Cell cell = { 0, 0 };
TextFont(systemFont);
TextSize(12);
- HLock(browser->uri_te);
- te = *(browser->uri_te);
-
- if (te->selStart == te->selEnd) {
+ if ((*(browser->uri_te))->selStart == (*(browser->uri_te))->selEnd) {
DisableItem(edit_menu, EDIT_MENU_CUT_ID);
DisableItem(edit_menu, EDIT_MENU_COPY_ID);
} else {
@@ -422,19 +434,12 @@ browser_update_menu(struct browser *browser)
EnableItem(edit_menu, EDIT_MENU_PASTE_ID);
EnableItem(edit_menu, EDIT_MENU_SELECT_ALL_ID);
-
- HUnlock(browser->uri_te);
}
void
browser_update_buttons(struct browser *browser)
{
- TERec *te;
- bool is_go;
-
if (browser->current_page) {
- HLock(browser->current_page);
-
if ((*(browser->current_page))->back_page)
HiliteControl(browser->back, 0);
else
@@ -444,8 +449,6 @@ browser_update_buttons(struct browser *browser)
HiliteControl(browser->fwd, 0);
else
HiliteControl(browser->fwd, 255);
-
- HUnlock(browser->current_page);
} else {
HiliteControl(browser->back, 255);
HiliteControl(browser->fwd, 255);
@@ -453,24 +456,15 @@ browser_update_buttons(struct browser *browser)
if (browser->loading_page) {
HiliteControl(browser->go_stop, 0);
- HLock(browser->go_stop);
- is_go = ((*(browser->go_stop))->contrlTitle[1] == 'G');
- HUnlock(browser->go_stop);
- if (is_go)
+ if ((*(browser->go_stop))->contrlTitle[1] == 'G')
SetCTitle(browser->go_stop, "\pStop");
} else {
- HLock(browser->uri_te);
- te = *(browser->uri_te);
- if (te->teLength)
+ if ((*(browser->uri_te))->teLength)
HiliteControl(browser->go_stop, 0);
else
HiliteControl(browser->go_stop, 255);
- HUnlock(browser->uri_te);
- HLock(browser->go_stop);
- is_go = ((*(browser->go_stop))->contrlTitle[1] == 'G');
- HUnlock(browser->go_stop);
- if (!is_go)
+ if ((*(browser->go_stop))->contrlTitle[1] != 'G')
SetCTitle(browser->go_stop, "\pGo");
}
}
@@ -494,18 +488,14 @@ browser_update(struct focusable *focusable, EventRecor
DrawGrowIconOnly(browser->win);
browser_draw_status(browser);
- HLock(browser->uri_te);
r = (*(browser->uri_te))->viewRect;
InsetRect(&r, -1, -1);
FrameRect(&r);
TEUpdate(&r, browser->uri_te);
- HUnlock(browser->uri_te);
- HLock(browser->output_tv);
r = (*(browser->output_tv))->view;
InsetRect(&r, -1, -1);
FrameRect(&r);
- HUnlock(browser->output_tv);
TVUpdate(browser->output_tv);
ValidRect(&browser->win->portRect);
@@ -531,18 +521,14 @@ browser_mouse_down(struct focusable *focusable, EventR
p = event->where;
GlobalToLocal(&p);
- HLock(browser->uri_te);
r = (*(browser->uri_te))->viewRect;
- HUnlock(browser->uri_te);
if (PtInRect(p, &r)) {
TEClick(p, ((event->modifiers & shiftKey) != 0), browser->uri_te);
browser_update_menu(browser);
return;
}
- HLock(browser->output_tv);
r = (*(browser->output_tv))->view;
- HUnlock(browser->output_tv);
if (PtInRect(p, &r)) {
TVClick(browser->output_tv, p,
((event->modifiers & shiftKey) != 0));
@@ -572,7 +558,7 @@ browser_mouse_down(struct focusable *focusable, EventR
if (TrackControl(control, p, 0L) && control == browser->go_stop) {
if (browser->loading_page) {
browser_stop_loading_page(browser);
- browser_statusf(browser, "Stopped loading");
+ browser_statusf(browser, "Stopped");
} else
browser_go(browser, 0);
} else if (TrackControl(control, p, 0L) && control == browser->back)
@@ -645,6 +631,7 @@ browser_handle_menu(struct focusable *focusable, short
TESetSelect(0, 1024 * 32, browser->uri_te);
return true;
}
+ browser_update_buttons(browser);
break;
}
@@ -654,15 +641,12 @@ browser_handle_menu(struct focusable *focusable, short
void
browser_go_uri(struct browser *browser, char *uristr)
{
- TERec *te;
Rect r;
TESetText(uristr, strlen(uristr), browser->uri_te);
TESetSelect(SHRT_MAX, SHRT_MAX, browser->uri_te);
- HLock(browser->uri_te);
r = (*(browser->uri_te))->viewRect;
- HUnlock(browser->uri_te);
TEUpdate(&r, browser->uri_te);
browser_go(browser, 0);
@@ -680,19 +664,14 @@ browser_go(struct browser *browser, short dir)
browser_statusf(browser, "");
if (dir == 0) {
- HLock(browser->uri_te);
- te = *(browser->uri_te);
- len = te->teLength;
+ len = (*(browser->uri_te))->teLength;
uristr = xmalloc(len + 1);
if (uristr == NULL) {
warn("Out of memory");
return;
}
- HLock(te->hText);
- memcpy(uristr, *(te->hText), len);
- HUnlock(te->hText);
+ memcpy(uristr, *((*(browser->uri_te))->hText), len);
uristr[len] = '\0';
- HUnlock(browser->uri_te);
browser_create_page(browser, uristr);
xfree(&uristr);
@@ -703,23 +682,23 @@ browser_go(struct browser *browser, short dir)
if (!pageh)
return;
- HLock(pageh);
- page = *pageh;
- if (dir == -1)
- opage = page->back_page;
- else
- opage = page->fwd_page;
- HUnlock(pageh);
+ opage = (dir == -1) ? (*pageh)->back_page : (*pageh)->fwd_page;
if (!opage)
return;
HLock(opage);
- if ((*opage)->handler->init(opage) && (*opage)->content_len == 0)
- /* page didn't load before, try again */
- browser->loading_page = opage;
- HLock(opage);
- (*opage)->handler->process(opage);
- HUnlock(opage);
+ browser->loading_page = opage;
+ browser_update_buttons(browser);
+
+ if ((*opage)->handler->init(*opage)) {
+ HUnlock(opage);
+ browser_commit_to_loading_page(browser);
+ } else {
+ (*opage)->handler->cleanup(*opage);
+ HUnlock(opage);
+ browser->loading_page = NULL;
+ browser_update_buttons(browser);
+ }
}
}
@@ -757,17 +736,19 @@ browser_create_page(struct browser *browser, char *uri
browser->loading_page = pageh;
browser_update_buttons(browser);
- if (handler->init(pageh))
- return pageh;
-
- /* handler failed, no point in keeping page */
- browser->loading_page = NULL;
- browser_update_buttons(browser);
HLock(pageh);
- page = *pageh;
- xfree(&page->uri);
- DisposeHandle(pageh);
- return NULL;
+ if (!handler->init(*pageh)) {
+ /* handler failed, no point in keeping page */
+ (*pageh)->handler->cleanup(*pageh);
+ browser->loading_page = NULL;
+ browser_update_buttons(browser);
+ xfree(&(*pageh)->uri);
+ DisposeHandle(pageh);
+ return NULL;
+ }
+
+ HUnlock(pageh);
+ return pageh;
}
warn("Could not parse URI \"%s\"", uristr);
@@ -865,10 +846,8 @@ browser_print_link(struct browser *browser, const char
return 0;
}
- HLock(browser->output_tv);
link->pos = (*(browser->output_tv))->text_length;
link->len = title_len ? title_len : uri_len;
- HUnlock(browser->output_tv);
link->uri = (char *)link + sizeof(struct browser_link);
memcpy(link->uri, uri, uri_len);
@@ -897,26 +876,21 @@ browser_print_link(struct browser *browser, const char
}
void
-browser_commit_to_page(struct browser *browser, page_handle pageh)
+browser_commit_to_loading_page(struct browser *browser)
{
- struct page *page;
page_handle tpage, fpage, bpage;
Rect r;
browser_free_links(browser);
- HLock(pageh);
- page = *pageh;
-
- if (browser->current_page == pageh)
+ if (browser->current_page == browser->loading_page)
Debugger();
- TESetText(page->uri->str, strlen(page->uri->str), browser->uri_te);
+ TESetText((*(browser->loading_page))->uri->str,
+ strlen((*(browser->loading_page))->uri->str), browser->uri_te);
TESetSelect(SHRT_MAX, SHRT_MAX, browser->uri_te);
- HLock(browser->uri_te);
r = (*(browser->uri_te))->viewRect;
- HUnlock(browser->uri_te);
TEUpdate(&r, browser->uri_te);
TVAutoCalc(browser->output_tv, true);
@@ -924,43 +898,85 @@ browser_commit_to_page(struct browser *browser, page_h
TVUpdateScrollbar(browser->output_tv, browser->output_tv_scroller);
if (browser->current_page) {
- HLock(browser->current_page);
fpage = (*(browser->current_page))->fwd_page;
bpage = (*(browser->current_page))->back_page;
- HUnlock(browser->current_page);
- if (pageh == bpage) {
+ if (browser->loading_page == bpage) {
/* we're going backwards in history */
- } else if (pageh == fpage) {
+ } else if (browser->loading_page == fpage) {
/* we're going fowards in history */
} else {
/* purge any forward pages because we're forking history now */
while (fpage) {
- HLock(fpage);
tpage = (*fpage)->fwd_page;
DisposeHandle(fpage);
fpage = tpage;
}
- HLock(browser->current_page);
- (*(browser->current_page))->fwd_page = pageh;
- HUnlock(browser->current_page);
-
- page->back_page = browser->current_page;
+ (*(browser->current_page))->fwd_page = browser->loading_page;
+ (*(browser->loading_page))->back_page = browser->current_page;
}
}
- browser->current_page = pageh;
- HUnlock(pageh);
-
+ browser->current_page = browser->loading_page;
browser_update_buttons(browser);
}
-size_t
-browser_grow_page_content(page_handle pageh, size_t len)
+bool
+browser_start_download(struct browser *browser, char *filename)
{
+ char buf[256], pfilename[32];
+ SFReply reply;
+ short error, frefnum;
+
+ if (filename) {
+ snprintf(buf, sizeof(buf), "Save %s:", filename);
+ strlcpy(pfilename, filename, sizeof(pfilename));
+ CtoPstr(pfilename);
+ } else {
+ snprintf(buf, sizeof(buf), "Save file:");
+ pfilename[0] = '0';
+ }
+ CtoPstr(buf);
+
+ SFPutFile(centered_sfput_dialog(), buf, pfilename, NULL, &reply);
+ if (!reply.good)
+ return false;
+
+ error = Create(reply.fName, reply.vRefNum, '????', '????');
+ if (error && error != dupFNErr) {
+ warn("Failed to create file %s: %d", PtoCstr(reply.fName), error);
+ return false;
+ }
+
+ error = FSOpen(reply.fName, reply.vRefNum, &frefnum);
+ if (error) {
+ warn("Failed to open new file %s: %d", PtoCstr(reply.fName), error);
+ return false;
+ }
+
+ error = SetEOF(frefnum, 0);
+ if (error) {
+ warn("Failed to truncate file %s: %d", PtoCstr(reply.fName), error);
+ return false;
+ }
+
+ (*(browser->loading_page))->download_frefnum = frefnum;
+ return true;
+}
+
+struct page *
+browser_grow_page_content(struct page *page, size_t len)
+{
unsigned long size, gsize;
+ page_handle pageh;
+ pageh = (page_handle)RecoverHandle(page);
+ if (pageh == NULL) {
+ Debugger();
+ return NULL;
+ }
+
HLock(pageh);
size = (*pageh)->content_size + MAX(len, PAGE_CONTENT_CHUNK_SIZE);
HUnlock(pageh);
@@ -969,12 +985,12 @@ browser_grow_page_content(page_handle pageh, size_t le
SetHandleSize(pageh, gsize);
if (MemError() != 0) {
warn("Out of memory growing page to %ld bytes", gsize);
- return 0;
+ return NULL;
}
HLock(pageh);
(*pageh)->content_size = size;
- HUnlock(pageh);
- return size;
+ /* keep locked */
+ return *pageh;
}
--- browser.h Sun Nov 3 11:22:13 2024
+++ browser.h Tue Nov 5 21:28:05 2024
@@ -23,6 +23,9 @@
#include "tcp.h"
#include "util.h"
+//#define BROWSER_DEBUGF(x) browser_statusf
+#define BROWSER_DEBUGF(x)
+
#define STYLE_NONE 0
#define STYLE_BOLD (1UL << 0)
#define STYLE_ITALIC (1UL << 1)
@@ -70,10 +73,9 @@ size_t browser_statusf(struct browser *browser, const
size_t browser_print_link(struct browser *browser, const char *url,
size_t url_len, const char *title, size_t title_len);
size_t browser_print(struct browser *browser, const char *str, size_t len);
-//#define BROWSER_DEBUGF(x) browser_statusf
-#define BROWSER_DEBUGF(x)
-void browser_commit_to_page(struct browser *browser, page_handle pageh);
-size_t browser_grow_page_content(page_handle pageh, size_t len);
+struct page * browser_grow_page_content(struct page *page, size_t len);
void browser_go_uri(struct browser *browser, char *uristr);
+void browser_commit_to_loading_page(struct browser *browser);
+bool browser_start_download(struct browser *browser, char *filename);
#endif
\ No newline at end of file
--- detritus.h Mon Nov 4 11:11:36 2024
+++ detritus.h Wed Nov 6 09:45:19 2024
@@ -72,21 +72,31 @@ struct page {
size_t content_len;
size_t content_pos;
struct uri_handler *handler;
- void *handler_cookie;
+ void *fetch_cookie;
char type[32];
+ short state;
short parse_state;
struct URI *redir_to;
+ short download_frefnum;
+ size_t download_len;
char content[];
};
struct uri_handler {
+ /* return a URI if this handler can process this string */
struct URI * (*parse_uri)(char *uristr);
+
/* do any post-init on a new page, like doing a request if no content */
- bool (*init)(page_handle pageh);
- /* process any request or parse existing content */
- bool (*process)(page_handle pageh);
+ bool (*init)(struct page *page);
+
+ /* continue fetching content */
+ bool (*fetch)(struct page *page);
+
+ /* parse existing content */
+ bool (*process)(struct page *page);
+
/* cleanup when done loading, such as freeing request */
- void (*cleanup)(page_handle pageh);
+ void (*cleanup)(struct page *page);
};
extern MenuHandle file_menu, edit_menu, bookmarks_menu;
--- finger.c Mon Nov 4 14:28:05 2024
+++ finger.c Wed Nov 6 12:57:34 2024
@@ -36,15 +36,15 @@ struct finger_request {
};
struct URI * finger_parse_uri(char *uristr);
-bool finger_init_request(page_handle pageh);
-bool finger_process(page_handle pageh);
-void finger_cleanup(page_handle pageh);
+bool finger_init_request(struct page *page);
+bool finger_fetch(struct page *page);
+bool finger_process(struct page *page);
+void finger_cleanup(struct page *page);
-static bool parse_content(struct page *page);
-
struct uri_handler finger_handler = {
finger_parse_uri,
finger_init_request,
+ finger_fetch,
finger_process,
finger_cleanup,
};
@@ -56,9 +56,8 @@ finger_parse_uri(char *uristr)
}
bool
-finger_init_request(page_handle pageh)
+finger_init_request(struct page *page)
{
- struct page *page;
struct finger_request *req = NULL;
size_t len;
char ip_s[12 + 3 + 1];
@@ -66,18 +65,16 @@ finger_init_request(page_handle pageh)
ip_addr ip, local_ip;
tcp_port port, local_port;
- HLock(pageh);
- page = *pageh;
if (page->content_len) {
/* already fetched, nothing to do here but reset */
page->content_pos = 0;
- goto done;
+ return true;
}
req = xmalloczero(sizeof(struct finger_request));
if (req == NULL) {
warn("Out of memory");
- goto fail;
+ return false;
}
if (page->uri->port == 0)
@@ -89,7 +86,7 @@ finger_init_request(page_handle pageh)
err = DNSResolveName(page->uri->hostname, &ip, NULL);
if (err) {
browser_statusf(page->browser, "Error: Failed resolving: %d", err);
- goto fail;
+ return false;
}
long2ip(ip, (char *)&ip_s);
@@ -100,7 +97,7 @@ finger_init_request(page_handle pageh)
sizeof(req->tcp_buf), NULL, NULL, NULL, false);
if (err) {
browser_statusf(page->browser, "Error: TCPCreate failed: %d", err);
- goto fail;
+ return false;
}
err = _TCPActiveOpen(&req->tcp_iopb, req->tcp_stream, ip,
@@ -109,7 +106,7 @@ finger_init_request(page_handle pageh)
browser_statusf(page->browser,
"Error: Failed connecting to %s (%s) port %d: %d",
page->uri->hostname, ip_s, page->uri->port, err);
- goto fail;
+ return false;
}
err = _TCPStatus(&req->tcp_iopb, req->tcp_stream, &req->tcp_status_pb,
@@ -118,7 +115,7 @@ finger_init_request(page_handle pageh)
browser_statusf(page->browser,
"Error: Failed TCPStatus on connection to %s (%s) port %d: %d",
page->uri->hostname, ip_s, page->uri->port, err);
- goto fail;
+ return false;
}
if (page->uri->path[0] == '\0' ||
@@ -140,154 +137,95 @@ finger_init_request(page_handle pageh)
NULL, false);
if (err) {
browser_statusf(page->browser, "Error: TCPSend failed: %d", err);
- goto fail;
+ return false;
}
- page->handler_cookie = req;
-
-done:
- HUnlock(pageh);
- browser_commit_to_page(page->browser, pageh);
-
+ page->fetch_cookie = req;
return true;
-
-fail:
- if (req) {
- if (req->tcp_stream) {
- _TCPAbort(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- }
-
- xfree(&req);
- page->handler_cookie = NULL;
- }
-
- HUnlock(pageh);
- return false;
}
void
-finger_cleanup(page_handle pageh)
+finger_cleanup(struct page *page)
{
struct finger_request *req;
- struct page *page;
- HLock(pageh);
- page = *pageh;
- req = (struct finger_request *)(page->handler_cookie);
-
- if (req) {
- if (req->tcp_stream) {
- _TCPAbort(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- }
-
- xfree(&page->handler_cookie);
- }
-
- HUnlock(pageh);
+ if (page->fetch_cookie == NULL)
+ return;
+
+ req = (struct finger_request *)(page->fetch_cookie);
+
+ if (req->tcp_stream)
+ _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
+
+ xfree(&page->fetch_cookie);
}
bool
-finger_process(page_handle pageh)
+finger_fetch(struct page *page)
{
struct finger_request *req;
- struct page *page;
- size_t size, len, n;
short err;
unsigned short slen;
- bool ret;
- HLock(pageh);
- page = *pageh;
-
- if (page->handler_cookie == NULL)
- goto parse;
+ if (page->fetch_cookie == NULL)
+ return false;
- req = (struct finger_request *)(page->handler_cookie);
+ req = (struct finger_request *)(page->fetch_cookie);
if (req->tcp_iopb.ioResult > 0 || CommandPeriodPressed()) {
BROWSER_DEBUGF((page->browser, "TCP I/O Result %d, disconnecting",
req->tcp_iopb.ioResult));
- goto finish_request;
+ return false;
}
err = _TCPStatus(&req->tcp_iopb, req->tcp_stream, &req->tcp_status_pb,
NULL, NULL, false);
if (err) {
browser_statusf(page->browser, "Error: Bad TCPStatus: %d", err);
- goto finish_request;
+ return false;
}
if (req->tcp_status_pb.connectionState !=
ConnectionStateEstablished) {
- BROWSER_DEBUGF((page->browser, "TCP connection closed (state %d)",
+ BROWSER_DEBUGF((page->browser, "TCP connection closed (state %d)",
req->tcp_status_pb.connectionState));
- goto finish_request;
+ return false;
}
- if (req->tcp_status_pb.amtUnreadData == 0)
- goto parse;
+
+ slen = req->tcp_status_pb.amtUnreadData;
+ if (slen == 0)
+ return true;
- if (page->content_len + req->tcp_status_pb.amtUnreadData >=
- page->content_size) {
- if (!browser_grow_page_content(pageh,
- req->tcp_status_pb.amtUnreadData))
+ if (page->content_len + slen >= page->content_size) {
+ page = browser_grow_page_content(page, slen);
+ if (page == NULL)
return false;
- HLock(pageh);
- page = *pageh;
- req = (struct finger_request *)(page->handler_cookie);
+ req = (struct finger_request *)(page->fetch_cookie);
}
- slen = req->tcp_status_pb.amtUnreadData;
err = _TCPRcv(&req->tcp_iopb, req->tcp_stream,
(Ptr)(page->content + page->content_len), &slen, NULL, NULL, false);
if (err) {
browser_statusf(page->browser, "Error: Failed TCPRcv: %d", err);
- goto finish_request;
+ return false;
}
+
page->content_len += slen;
browser_statusf(page->browser, "Read %ld bytes", page->content_len);
- goto parse;
-
-finish_request:
- finger_cleanup(pageh);
-
-parse:
- HLock(pageh);
- page = *pageh;
-
- if (page->content_pos == page->content_len) {
- if (!page->handler_cookie) {
- /* nothing left to do */
- return false;
- }
- HUnlock(pageh);
- return true;
- }
-
- TVAutoCalc(page->browser->output_tv, false);
- ret = parse_content(page);
- TVCalcLines(page->browser->output_tv);
- TVUpdate(page->browser->output_tv);
- TVUpdateScrollbar(page->browser->output_tv,
- page->browser->output_tv_scroller);
-
- if (ret) {
- HUnlock(pageh);
- return true;
- }
-
-request_fail:
- HUnlock(pageh);
- return false;
+ return true;
}
-static bool
-parse_content(struct page *page)
+bool
+finger_process(struct page *page)
{
long n, plines = 0;
-
+ bool ret = true;
+
+ if (page->content_pos == page->content_len)
+ return (page->fetch_cookie != NULL);
+
+ TVAutoCalc(page->browser->output_tv, false);
page->browser->style = STYLE_PRE;
/* text file, convert newlines and display */
@@ -322,16 +260,19 @@ parse_content(struct page *page)
}
}
- if (!page->handler_cookie &&
+ if (page->fetch_cookie == NULL &&
page->content_pos < page->content_len) {
+ /* no request to fetch more content, finish */
browser_print(page->browser, page->content + page->content_pos,
page->content_len - page->content_pos);
page->content_pos = page->content_len;
- return false;
+ ret = false;
}
- if (page->handler_cookie)
- return true;
+ TVCalcLines(page->browser->output_tv);
+ TVUpdate(page->browser->output_tv);
+ TVUpdateScrollbar(page->browser->output_tv,
+ page->browser->output_tv_scroller);
- return false;
+ return ret;
}
--- gemini.c Mon Nov 4 14:28:38 2024
+++ gemini.c Wed Nov 6 13:06:39 2024
@@ -54,20 +54,21 @@ struct gemini_request {
};
struct URI * gemini_parse_uri(char *uristr);
-bool gemini_init_request(page_handle pageh);
-bool gemini_process(page_handle pageh);
-void gemini_cleanup(page_handle pageh);
+bool gemini_init_request(struct page *page);
+bool gemini_fetch(struct page *page);
+bool gemini_process(struct page *page);
+void gemini_cleanup(struct page *page);
static bool shuffle_read_tls_ciphertext(struct page *page);
static bool shuffle_read_tcp_ciphertext(struct page *page, short space);
static bool shuffle_tls_send_plaintext(struct page *page, short space);
static bool shuffle_tls_read_plaintext(struct page *page);
static bool parse_header(struct page *page, char *str, size_t len);
-static bool parse_content(struct page *page);
struct uri_handler gemini_handler = {
gemini_parse_uri,
gemini_init_request,
+ gemini_fetch,
gemini_process,
gemini_cleanup,
};
@@ -79,9 +80,8 @@ gemini_parse_uri(char *uristr)
}
bool
-gemini_init_request(page_handle pageh)
+gemini_init_request(struct page *page)
{
- struct page *page;
struct gemini_request *req = NULL;
struct tls_init_request tls_req;
char ip_s[12 + 3 + 1];
@@ -90,24 +90,22 @@ gemini_init_request(page_handle pageh)
ip_addr ip, local_ip;
tcp_port port, local_port;
- HLock(pageh);
- page = *pageh;
if (page->content_len) {
/* already fetched, nothing to do here but reset */
page->content_pos = 0;
page->parse_state = PARSE_STATE_HEADER;
- goto done;
+ return true;
}
if (!scsi_can_do_tls()) {
warn("No TLS accelerator found, cannot make Gemini requests");
- goto fail;
+ return false;
}
req = xmalloczero(sizeof(struct gemini_request));
if (req == NULL) {
warn("Out of memory");
- goto fail;
+ return false;
}
if (page->uri->port == 0)
@@ -177,84 +175,67 @@ gemini_init_request(page_handle pageh)
goto fail;
}
- page->handler_cookie = req;
-
-done:
- HUnlock(pageh);
+ page->fetch_cookie = req;
return true;
fail:
if (req) {
- if (req->tcp_stream) {
- _TCPAbort(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
+ if (req->tcp_stream)
_TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- }
xfree(&req);
- page->handler_cookie = NULL;
+ page->fetch_cookie = NULL;
}
- HUnlock(pageh);
return false;
}
void
-gemini_cleanup(page_handle pageh)
+gemini_cleanup(struct page *page)
{
struct gemini_request *req;
- struct page *page;
- HLock(pageh);
- page = *pageh;
-
- if (page->handler_cookie) {
- req = (struct gemini_request *)(page->handler_cookie);
-
- if (req->tcp_stream) {
- _TCPAbort(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- }
-
- if (req->tls_id)
- scsi_tls_close(req->tls_id);
+ if (page->fetch_cookie == NULL)
+ return;
- xfree(&page->handler_cookie);
- }
+ req = (struct gemini_request *)(page->fetch_cookie);
- HUnlock(pageh);
+ if (req->tcp_stream)
+ _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
+
+ if (req->tls_id)
+ scsi_tls_close(req->tls_id);
+
+ xfree(&page->fetch_cookie);
}
bool
-gemini_process(page_handle pageh)
+gemini_fetch(struct page *page)
{
+ page_handle pageh;
struct gemini_request *req;
- struct page *page;
size_t len;
unsigned short slen;
short err, status;
short cipherspace, plainspace, error;
bool ret;
- HLock(pageh);
- page = *pageh;
-
- if (page->handler_cookie == NULL) {
- ret = parse_content(page);
- HUnlock(pageh);
- return ret;
- }
+ if (page->fetch_cookie == NULL)
+ return false;
- req = (struct gemini_request *)(page->handler_cookie);
+ req = (struct gemini_request *)(page->fetch_cookie);
if (req->tcp_iopb.ioResult > 0 || CommandPeriodPressed()) {
BROWSER_DEBUGF((page->browser, "TCP I/O Result %d, disconnecting",
req->tcp_iopb.ioResult));
- goto finish_request;
+ return false;
}
status = scsi_tls_status(req->tls_id, &cipherspace, &plainspace,
&error);
+ pageh = (page_handle)RecoverHandle(page);
+
while (status != 0) {
if ((status & 0x1) && page->content_pos == page->content_len) {
/* closed */
@@ -262,22 +243,21 @@ gemini_process(page_handle pageh)
browser_statusf(page->browser,
"Error: TLS handshake failed: %d (TLS status 0x%x)",
error, status);
- goto finish_request;
+ return false;
}
if (status & 0x2) {
/* tls has ciphertext for tcp */
if (!shuffle_read_tls_ciphertext(page))
- goto finish_request;
- HLock(pageh);
- page = *pageh;
+ return false;
status &= ~0x2;
}
if ((status & 0x10) || page->content_pos < page->content_len) {
/* tls has plaintext data for us */
if (!shuffle_tls_read_plaintext(page))
- goto finish_request;
+ return false;
+ /* handle may have grown */
HLock(pageh);
page = *pageh;
status &= ~0x10;
@@ -286,34 +266,24 @@ gemini_process(page_handle pageh)
if (status & 0x8) {
/* tls can read plaintext from us */
if (!shuffle_tls_send_plaintext(page, plainspace))
- goto finish_request;
- HLock(pageh);
- page = *pageh;
+ return false;
status &= ~0x8;
}
if (status & 0x4) {
/* tls can read ciphertext from tcp */
if (!shuffle_read_tcp_ciphertext(page, cipherspace))
- goto finish_request;
- HLock(pageh);
- page = *pageh;
+ return false;
status &= ~0x4;
}
if (status) {
browser_statusf(page->browser, "TLS status is 0x%x?", status);
- goto finish_request;
+ return false;
}
}
- HUnlock(pageh);
return true;
-
-finish_request:
- HUnlock(pageh);
- gemini_cleanup(pageh);
- return false;
}
static bool
@@ -326,7 +296,7 @@ shuffle_read_tls_ciphertext(struct page *page)
/* read ciphertext from TLS and send it out TCP */
- req = (struct gemini_request *)(page->handler_cookie);
+ req = (struct gemini_request *)(page->fetch_cookie);
len = scsi_tls_read(req->tls_id, &buf, 0, true);
if (len == 0 || buf == NULL) {
@@ -365,7 +335,7 @@ shuffle_read_tcp_ciphertext(struct page *page, short s
/* read ciphertext from TCP and send it to TLS */
- req = (struct gemini_request *)(page->handler_cookie);
+ req = (struct gemini_request *)(page->fetch_cookie);
if (req->tcp_input_len == sizeof(req->tcp_input) ||
req->tcp_done_reading)
@@ -445,7 +415,7 @@ shuffle_tls_send_plaintext(struct page *page, short sp
/* send any plaintext from us to TLS */
- req = (struct gemini_request *)(page->handler_cookie);
+ req = (struct gemini_request *)(page->fetch_cookie);
if (req->message_len == 0)
return true;
@@ -492,19 +462,17 @@ shuffle_tls_read_plaintext(struct page *page)
/* read as much plaintext from TLS as we can buffer */
- req = (struct gemini_request *)(page->handler_cookie);
+ req = (struct gemini_request *)(page->fetch_cookie);
len = scsi_tls_read(req->tls_id, &buf, PAGE_CONTENT_CHUNK_SIZE, false);
if (len == 0)
return true;
if (page->content_len + len >= page->content_size) {
- pageh = (page_handle)RecoverHandle(page);
- if (!browser_grow_page_content(pageh, len))
+ page = browser_grow_page_content(page, len);
+ if (page == NULL)
return false;
- HLock(pageh);
- page = *pageh;
- req = (struct gemini_request *)(page->handler_cookie);
+ req = (struct gemini_request *)(page->fetch_cookie);
}
memcpy(page->content + page->content_len, buf, len);
@@ -512,16 +480,19 @@ shuffle_tls_read_plaintext(struct page *page)
browser_statusf(page->browser, "Read %ld bytes", page->content_len);
- return parse_content(page);
+ return true;
}
static bool
-parse_content(struct page *page)
+gemini_process(struct page *page)
{
+ page_handle pageh;
size_t n, trail, skip, len;
char c;
bool newline;
+ pageh = (page_handle)RecoverHandle(page);
+
handle_state:
switch (page->parse_state) {
case PARSE_STATE_HEADER: {
@@ -540,10 +511,11 @@ handle_state:
return false;
}
- if (strcmp(page->type, "text/gemini") == 0) {
+ if (strncmp(page->type, "text/gemini", 10) == 0) {
page->parse_state = PARSE_STATE_GEMTEXT;
- browser_commit_to_page(page->browser,
- (page_handle)RecoverHandle(page));
+ browser_commit_to_loading_page(page->browser);
+ HLock(pageh);
+ page = *pageh;
} else
page->parse_state = PARSE_STATE_DOWNLOAD;
@@ -553,7 +525,7 @@ handle_state:
goto handle_state;
}
- if (page->handler_cookie == NULL)
+ if (page->fetch_cookie == NULL)
/* no more data will be coming */
return false;
@@ -583,7 +555,7 @@ handle_state:
len--;
trail++;
}
- } else if (page->handler_cookie != NULL) {
+ } else if (page->fetch_cookie != NULL) {
/*
* No newline found at the end of the buffer, but the
* buffer isn't full so wait for more data.
--- gopher.c Mon Nov 4 14:29:11 2024
+++ gopher.c Wed Nov 6 12:57:26 2024
@@ -23,6 +23,8 @@
#define GOPHER_PORT 70
+static const char showable_types[] = "013i";
+
struct gopher_request {
unsigned char tcp_buf[(4 * 1500) + 2048]; /* 4*MTU + tcp_input */
@@ -36,16 +38,17 @@ struct gopher_request {
};
struct URI * gopher_parse_uri(char *uristr);
-bool gopher_init_request(page_handle pageh);
-bool gopher_process(page_handle pageh);
-void gopher_cleanup(page_handle pageh);
+bool gopher_init_request(struct page *page);
+bool gopher_fetch(struct page *page);
+bool gopher_process(struct page *page);
+void gopher_cleanup(struct page *page);
-static bool parse_content(struct page *page);
static void gopher_print_menu(struct page *page, char *line, size_t len);
struct uri_handler gopher_handler = {
gopher_parse_uri,
gopher_init_request,
+ gopher_fetch,
gopher_process,
gopher_cleanup,
};
@@ -57,28 +60,25 @@ gopher_parse_uri(char *uristr)
}
bool
-gopher_init_request(page_handle pageh)
+gopher_init_request(struct page *page)
{
- struct page *page;
struct gopher_request *req = NULL;
size_t len;
- char ip_s[12 + 3 + 1];
+ char ip_s[12 + 3 + 1], *filename;
short err;
ip_addr ip, local_ip;
tcp_port port, local_port;
- HLock(pageh);
- page = *pageh;
if (page->content_len) {
/* already fetched, nothing to do here but reset */
page->content_pos = 0;
- goto done;
+ return true;
}
req = xmalloczero(sizeof(struct gopher_request));
if (req == NULL) {
warn("Out of memory");
- goto fail;
+ return false;
}
if (page->uri->port == 0)
@@ -90,7 +90,7 @@ gopher_init_request(page_handle pageh)
err = DNSResolveName(page->uri->hostname, &ip, NULL);
if (err) {
browser_statusf(page->browser, "Error: Failed resolving: %d", err);
- goto fail;
+ return false;
}
long2ip(ip, (char *)&ip_s);
@@ -101,7 +101,7 @@ gopher_init_request(page_handle pageh)
sizeof(req->tcp_buf), NULL, NULL, NULL, false);
if (err) {
browser_statusf(page->browser, "Error: TCPCreate failed: %d", err);
- goto fail;
+ return false;
}
err = _TCPActiveOpen(&req->tcp_iopb, req->tcp_stream, ip,
@@ -110,7 +110,7 @@ gopher_init_request(page_handle pageh)
browser_statusf(page->browser,
"Error: Failed connecting to %s (%s) port %d: %d",
page->uri->hostname, ip_s, page->uri->port, err);
- goto fail;
+ return false;
}
err = _TCPStatus(&req->tcp_iopb, req->tcp_stream, &req->tcp_status_pb,
@@ -119,7 +119,7 @@ gopher_init_request(page_handle pageh)
browser_statusf(page->browser,
"Error: Failed TCPStatus on connection to %s (%s) port %d: %d",
page->uri->hostname, ip_s, page->uri->port, err);
- goto fail;
+ return false;
}
/*
@@ -137,7 +137,7 @@ gopher_init_request(page_handle pageh)
req->selector_len = snprintf(req->selector, sizeof(req->selector),
"%s\r\n", page->uri->path + 2);
}
-
+
browser_statusf(page->browser, "Connected to %s, sending request...",
page->uri->hostname);
@@ -149,166 +149,144 @@ gopher_init_request(page_handle pageh)
NULL, false);
if (err) {
browser_statusf(page->browser, "Error: TCPSend failed: %d", err);
- goto fail;
+ return false;
}
- page->handler_cookie = req;
-
-done:
- HUnlock(pageh);
- browser_commit_to_page(page->browser, pageh);
+ page->fetch_cookie = req;
- return true;
-
-fail:
- if (req) {
- if (req->tcp_stream) {
- _TCPAbort(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
+ if (strchr(showable_types, page->type[0]) == NULL) {
+ if (req->selector_len == 2)
+ filename = NULL;
+ else {
+ filename = strrchr(page->uri->path + 2, '/');
+ if (filename && filename[0] == '/')
+ filename++;
+ if (!browser_start_download(page->browser, filename))
+ return false;
}
+ } else
+ browser_commit_to_loading_page(page->browser);
- xfree(&req);
- page->handler_cookie = NULL;
- }
-
- HUnlock(pageh);
- return false;
+ return true;
}
void
-gopher_cleanup(page_handle pageh)
+gopher_cleanup(struct page *page)
{
struct gopher_request *req;
- struct page *page;
- HLock(pageh);
- page = *pageh;
- req = (struct gopher_request *)(page->handler_cookie);
-
- if (req) {
- if (req->tcp_stream) {
- _TCPAbort(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
- }
-
- xfree(&page->handler_cookie);
- }
-
- HUnlock(pageh);
+ if (page->fetch_cookie == NULL)
+ return;
+
+ req = (struct gopher_request *)(page->fetch_cookie);
+
+ if (req->tcp_stream)
+ _TCPRelease(&req->tcp_iopb, req->tcp_stream, NULL, NULL, false);
+
+ xfree(&page->fetch_cookie);
}
bool
-gopher_process(page_handle pageh)
+gopher_fetch(struct page *page)
{
struct gopher_request *req;
- struct page *page;
- size_t size, len, n;
short err;
unsigned short slen;
- bool ret;
+ unsigned long llen, ollen;
+ Ptr rcvptr;
- HLock(pageh);
- page = *pageh;
-
- if (page->handler_cookie == NULL)
- goto parse;
+ if (page->fetch_cookie == NULL)
+ return false;
- req = (struct gopher_request *)(page->handler_cookie);
+ req = (struct gopher_request *)(page->fetch_cookie);
if (req->tcp_iopb.ioResult > 0 || CommandPeriodPressed()) {
BROWSER_DEBUGF((page->browser, "TCP I/O Result %d, disconnecting",
req->tcp_iopb.ioResult));
- goto finish_request;
+ return false;
}
err = _TCPStatus(&req->tcp_iopb, req->tcp_stream, &req->tcp_status_pb,
NULL, NULL, false);
if (err) {
browser_statusf(page->browser, "Error: Bad TCPStatus: %d", err);
- goto finish_request;
+ return false;
}
if (req->tcp_status_pb.connectionState !=
ConnectionStateEstablished) {
- BROWSER_DEBUGF((page->browser, "TCP connection closed (state %d)",
+ BROWSER_DEBUGF((page->browser, "TCP connection closed (state %d)",
req->tcp_status_pb.connectionState));
- goto finish_request;
+ return false;
}
- if (req->tcp_status_pb.amtUnreadData == 0)
- goto parse;
+
+ slen = req->tcp_status_pb.amtUnreadData;
+ if (slen == 0)
+ return true;
- if (page->content_len + req->tcp_status_pb.amtUnreadData >=
- page->content_size) {
- if (!browser_grow_page_content(pageh,
- req->tcp_status_pb.amtUnreadData))
- return false;
- HLock(pageh);
- page = *pageh;
- req = (struct gopher_request *)(page->handler_cookie);
+ if (page->download_frefnum) {
+ rcvptr = (Ptr)(page->content);
+ if (slen > page->content_size)
+ slen = page->content_size;
+ } else {
+ if (page->content_len + slen >= page->content_size) {
+ page = browser_grow_page_content(page, slen);
+ if (page == NULL)
+ return false;
+ req = (struct gopher_request *)(page->fetch_cookie);
+ }
+ rcvptr = (Ptr)(page->content + page->content_len);
}
-
- slen = req->tcp_status_pb.amtUnreadData;
- err = _TCPRcv(&req->tcp_iopb, req->tcp_stream,
- (Ptr)(page->content + page->content_len), &slen, NULL, NULL, false);
+
+ err = _TCPRcv(&req->tcp_iopb, req->tcp_stream, rcvptr, &slen, NULL,
+ NULL, false);
if (err) {
browser_statusf(page->browser, "Error: Failed TCPRcv: %d", err);
- goto finish_request;
+ return false;
}
- page->content_len += slen;
- browser_statusf(page->browser, "Read %ld bytes", page->content_len);
- if ((page->type[0] == '0' || page->type[0] == '1' ||
- page->type[0] == 3) && page->content_len >= 3 &&
- (page->content_len == 3 ||
- page->content[page->content_len - 4] == '\n') &&
- page->content[page->content_len - 3] == '.' &&
- page->content[page->content_len - 2] == '\r' &&
- page->content[page->content_len - 1] == '\n') {
- /* ".\r\n" is end of transfer */
- page->content_len -= 3;
- goto finish_request;
- }
-
- goto parse;
-
-finish_request:
- gopher_cleanup(pageh);
-
-parse:
- HLock(pageh);
- page = *pageh;
+ if (page->download_frefnum) {
+ ollen = llen = slen;
+ err = FSWrite(page->download_frefnum, &llen, page->content);
+ if (err || ollen != llen) {
+ warn("Failed to write: %d", err);
+ return false;
+ }
+
+ page->download_len += llen;
+ browser_statusf(page->browser, "Wrote %ld bytes",
+ page->download_len);
+ } else {
+ page->content_len += slen;
+ browser_statusf(page->browser, "Read %ld bytes", page->content_len);
- if (page->content_pos == page->content_len) {
- if (!page->handler_cookie) {
- /* nothing left to do */
+ if (strchr(showable_types, page->type[0]) &&
+ page->content_len >= 3 &&
+ (page->content_len == 3 ||
+ page->content[page->content_len - 4] == '\n') &&
+ page->content[page->content_len - 3] == '.' &&
+ page->content[page->content_len - 2] == '\r' &&
+ page->content[page->content_len - 1] == '\n') {
+ /* ".\r\n" is end of transfer */
+ page->content_len -= 3;
return false;
}
- HUnlock(pageh);
- return true;
}
- TVAutoCalc(page->browser->output_tv, false);
- ret = parse_content(page);
- TVCalcLines(page->browser->output_tv);
- TVUpdate(page->browser->output_tv);
- TVUpdateScrollbar(page->browser->output_tv,
- page->browser->output_tv_scroller);
-
- if (ret) {
- HUnlock(pageh);
- return true;
- }
-
-request_fail:
- HUnlock(pageh);
- return false;
+ return true;
}
-static bool
-parse_content(struct page *page)
+bool
+gopher_process(struct page *page)
{
long n, plines = 0;
+ bool ret = true;
+ if (page->content_pos == page->content_len)
+ return (page->fetch_cookie != NULL);
+
+ TVAutoCalc(page->browser->output_tv, false);
+
if (page->type[0] == '1') {
/* gopher menu */
for (n = page->content_pos; n < page->content_len; n++) {
@@ -330,12 +308,12 @@ parse_content(struct page *page)
}
}
- if (!page->handler_cookie &&
+ if (page->fetch_cookie == NULL &&
page->content_pos < page->content_len) {
gopher_print_menu(page, page->content + page->content_pos,
page->content_len - page->content_pos);
page->content_pos = page->content_len;
- return false;
+ ret = false;
}
} else if (page->type[0] == '0') {
/* text file, convert newlines and display */
@@ -370,24 +348,27 @@ parse_content(struct page *page)
}
}
- if (!page->handler_cookie &&
+ if (page->fetch_cookie == NULL &&
page->content_pos < page->content_len) {
browser_print(page->browser, page->content + page->content_pos,
page->content_len - page->content_pos);
page->content_pos = page->content_len;
- return false;
+ ret = false;
}
} else {
/* anything else, just download it */
browser_print(page->browser, page->content + page->content_pos,
page->content_len - page->content_pos);
page->content_pos = page->content_len;
+ ret = false;
}
- if (page->handler_cookie)
- return true;
+ TVCalcLines(page->browser->output_tv);
+ TVUpdate(page->browser->output_tv);
+ TVUpdateScrollbar(page->browser->output_tv,
+ page->browser->output_tv_scroller);
- return false;
+ return ret;
}
static void
@@ -435,7 +416,9 @@ gopher_print_menu(struct page *page, char *line, size_
tlen = snprintf(uri, sizeof(uri), "gopher://%s/%c%s", hostname,
type, selector);
+ page->browser->style |= STYLE_BOLD;
browser_print_link(page->browser, uri, tlen, label, strlen(label));
+ page->browser->style &= ~(STYLE_BOLD);
browser_print(page->browser, "\r", 1);
break;
}
--- main.c Mon Nov 4 11:15:12 2024
+++ main.c Tue Nov 5 20:47:53 2024
@@ -261,7 +261,7 @@ parse_uri(char *uristr, char *restrict_protocol)
if (count = 0, sscanf(uristr,
"%" STR(URI_MAX_PROTOCOL_LEN) "[^:]://%"
STR(URI_MAX_HOSTNAME_LEN) "[^/]%"
- STR(URI_MAX_PATH_LEN) "s%n",
+ STR(URI_MAX_PATH_LEN) "[ -~]%n", /* %s stops at whitespace, use all vis */
&protocol, &hostname, &path, &count) == 3 && count > 10)
goto parse_ok;
@@ -318,6 +318,7 @@ parse_ok:
uri->hostname[hostname_len] = '\0';
data += hostname_len + 1;
+ /* TODO: cut at ? and put that in query */
uri->path = data;
memcpy(uri->path, path, path_len);
uri->path[path_len] = '\0';