jcs
/subtext
/amendments
/495
nomodem: Read upload data from ibuf in chunks to speed it up a little
jcs made amendment 495 about 1 year ago
--- nomodem.c Thu Apr 27 00:18:09 2023
+++ nomodem.c Thu Apr 27 10:56:12 2023
@@ -81,6 +81,14 @@ nomodem_receive(struct session *s, char *path)
xfree(&ns);
return NULL;
}
+
+ ns->buf_size = sizeof(ns->session->ibuf);
+ ns->buf = xmalloc(ns->buf_size);
+ if (ns->buf == NULL) {
+ xfree(&ns->file_path);
+ xfree(&ns);
+ return NULL;
+ }
ns->file = fopen(ns->file_path, "wb+");
if (ns->file == NULL) {
@@ -130,10 +138,9 @@ nomodem_get_char(struct nomodem_session *ns)
bool
nomodem_continue(struct nomodem_session *ns)
{
- size_t size, rsize, pos;
+ size_t size, rsize, pos, tsize;
short resp;
unsigned short file_name_size, file_name_pos;
- unsigned char b;
switch (ns->mode) {
case NOMODEM_MODE_SENDING:
@@ -280,17 +287,31 @@ nomodem_continue(struct nomodem_session *ns)
return false;
size |= (unsigned long)(resp & 0xff);
- /* TODO: read chunks directly from ibuf */
- for (rsize = 0; rsize < size; rsize++) {
- resp = nomodem_get_char(ns);
- if (resp < 0)
+ if (size > (1024 * 10)) {
+ session_logf(ns->session, "[nomodem] Chunk size too large: %ld",
+ size);
+ return false;
+ }
+
+ for (rsize = 0; rsize < size; ) {
+ tsize = session_get_chars(ns->session, ns->buf,
+ MIN(ns->buf_size, size - rsize));
+ if (ns->session->ending || nomodem_timed_out(ns))
return false;
- b = resp;
- if (fwrite(&b, 1, 1, ns->file) != 1) {
+ if (tsize == 0) {
+ uthread_yield();
+ continue;
+ }
+
+ ns->last_input = Time;
+
+ if (fwrite(ns->buf, 1, tsize, ns->file) != tsize) {
session_logf(ns->session, "[nomodem] Failed writing to %s",
ns->file_path);
return false;
}
+
+ rsize += tsize;
}
session_printf(ns->session, "%c", (char)NOMODEM_ACK);
@@ -314,6 +335,8 @@ nomodem_finish(struct nomodem_session **nsp)
if (ns->file)
fclose(ns->file);
-
+
+ if (ns->buf)
+ xfree(&ns->buf);
xfree(nsp);
}
--- nomodem.h Wed Apr 26 21:24:47 2023
+++ nomodem.h Thu Apr 27 11:08:00 2023
@@ -54,6 +54,9 @@ struct nomodem_session {
bool need_header;
bool need_header_ack;
unsigned long last_input;
+
+ unsigned char *buf;
+ size_t buf_size;
};
struct nomodem_session * nomodem_send(struct session *s, FILE *fp,