jcs
/subtext
/amendments
/492
folder: Add NoModem support
jcs made amendment 492 about 1 year ago
--- folder.c Thu Apr 6 13:47:25 2023
+++ folder.c Wed Apr 26 23:50:36 2023
@@ -22,6 +22,7 @@
#include "subtext.h"
#include "ansi.h"
#include "folder.h"
+#include "nomodem.h"
#include "sha1.h"
#include "user.h"
#include "zmodem.h"
@@ -343,8 +344,9 @@ folder_upload(struct session *s, struct folder *folder
struct folder_file file = { 0 };
struct stat sb;
struct zmodem_session *zs;
- char *upload_path = NULL, *tmp = NULL;
- size_t size, rsize;
+ struct nomodem_session *ns;
+ char *upload_path = NULL, *tmp = NULL, *file_name;
+ size_t size, rsize, file_size;
short c, n, error;
if (!s->user) {
@@ -358,13 +360,24 @@ folder_upload(struct session *s, struct folder *folder
strlcpy(file.filename, initial_filename, sizeof(file.filename));
file.uploader_user_id = s->user->id;
-
+
+ upload_path = xmalloc(FILENAME_MAX);
+ if (upload_path == NULL)
+ return 0;
+
session_printf(s, "{{B}}Upload New File{{/B}}\r\n");
+ if (s->can_nomodem) {
+ session_printf(s,
+ "To begin your upload, press Enter and choose a file (only one file\r\n");
+ session_printf(s,
+ "can be uploaded at a time).\r\n");
+ } else {
+ session_printf(s,
+ "To begin your ZMODEM upload, press Enter and choose a file through\r\n");
+ session_printf(s,
+ "your terminal program (only one file can be uploaded at a time).\r\n");
+ }
session_printf(s,
- "To begin your ZMODEM upload, press Enter and choose a file through\r\n");
- session_printf(s,
- "your terminal program (only one file can be uploaded at a time).\r\n");
- session_printf(s,
"\r\n"
"You'll then be given the option to change the filename and enter a\r\n"
"description for the file.\r\n"
@@ -373,80 +386,118 @@ folder_upload(struct session *s, struct folder *folder
session_flush(s);
session_pause_return(s, 0, "when you are ready...");
- upload_path = xmalloc(FILENAME_MAX);
- if (upload_path == NULL)
- return 0;
snprintf(upload_path, FILENAME_MAX, "%s:upload-%08lx%08lx",
folder->path, xorshift32(), xorshift32());
-
- zs = ZCreateReceiver(s, upload_path);
- if (zs == NULL) {
- xfree(&upload_path);
- return 0;
+
+ if (s->can_nomodem) {
+ ns = nomodem_receive(s, upload_path);
+ if (ns == NULL) {
+ xfree(&upload_path);
+ return 0;
+ }
+ } else {
+ zs = ZCreateReceiver(s, upload_path);
+ if (zs == NULL) {
+ xfree(&upload_path);
+ return 0;
+ }
+ zs->DoIACEscape = s->is_telnet;
+
+ ZInit(zs);
+ s->direct_output = true;
}
- zs->DoIACEscape = s->is_telnet;
- ZInit(zs);
- s->transferring_file = true;
session_flush(s);
session_logf(s, "[%s] Receiving uploaded file to %s", folder->name,
upload_path);
while (!s->ending) {
- if (ZHaveTimedOut(zs)) {
- ZTimeOutProc(zs);
- session_logf(s, "[%s] Transfer timed out, canceling",
- folder->name);
- break;
+ if (s->can_nomodem) {
+ if (nomodem_timed_out(ns))
+ goto timed_out;
+ if (!nomodem_continue(ns))
+ break;
+ } else {
+ if (ZHaveTimedOut(zs)) {
+ ZTimeOutProc(zs);
+ goto timed_out;
+ }
+
+ if (!ZParse(zs))
+ break;
}
- if (!ZParse(zs))
- break;
-
if (s->obuflen)
session_flush(s);
+
+ continue;
+timed_out:
+ session_logf(s, "[%s] Transfer timed out, canceling", folder->name);
+ break;
}
/* flush the pipes */
s->obuflen = 0;
uthread_msleep(1000);
session_clear_input(s);
- s->transferring_file = false;
+ s->direct_output = false;
- if (zs->file) {
- fclose(zs->file);
- zs->file = NULL;
+ if (s->can_nomodem) {
+ file_size = ns->file_size;
+ if (ns->file) {
+ fclose(ns->file);
+ ns->file = NULL;
+ }
+ } else {
+ if (zs->file) {
+ fclose(zs->file);
+ zs->file = NULL;
+ }
+ file_size = zs->file_size;
}
-
+
session_printf(s, "\r\n\r\n");
- if (stat(upload_path, &sb) != 0) {
+ if (stat(upload_path, &sb) != 0 || sb.st_size == 0) {
session_logf(s, "[%s] Failed receiving upload, no temp file",
folder->name);
session_printf(s, "Failed receiving file, aborting.\r\n");
session_pause_return(s, CONTROL_C, "to continue...");
- ZDestroy(zs);
- zs = NULL;
+ if (s->can_nomodem) {
+ nomodem_finish(&ns);
+ } else {
+ ZDestroy(zs);
+ zs = NULL;
+ }
xfree(&upload_path);
return 0;
}
- if (sb.st_size != zs->file_size) {
+ if (sb.st_size != file_size) {
session_logf(s, "[%s] Received uploaded file of size %ld but "
"supposed to be %ld, canceling", folder->name, sb.st_size,
- zs->file_size);
+ file_size);
session_printf(s,
"Uploaded file expected to be {{B}}%ld{{/B}} byte%s, but "
"received\r\n"
"{{B}}%ld{{/B}} byte%s. Deleting file and canceling upload.\r\n",
- zs->file_size, zs->file_size == 1 ? "" : "s",
+ file_size, file_size == 1 ? "" : "s",
sb.st_size, sb.st_size == 1 ? "" : "s");
session_pause_return(s, CONTROL_C, "to continue...");
- ZDestroy(zs);
- zs = NULL;
+ if (s->can_nomodem) {
+ nomodem_finish(&ns);
+ } else {
+ ZDestroy(zs);
+ zs = NULL;
+ }
goto file_upload_cancel;
}
- strlcpy(file.filename, zs->file_name, sizeof(file.filename));
+ if (s->can_nomodem)
+ file_name = ns->file_name;
+ else
+ file_name = zs->file_name;
+
+ strlcpy(file.filename, file_name, sizeof(file.filename));
file.size = sb.st_size;
session_printf(s, "Successfully received file {{B}}%s{{/B}} of size "
@@ -457,9 +508,12 @@ folder_upload(struct session *s, struct folder *folder
session_logf(s, "[%s] Received uploaded file %s of size %ld",
folder->name, file.filename, file.size);
- /* this will fclose and free zs */
- ZDestroy(zs);
- zs = NULL;
+ if (s->can_nomodem) {
+ nomodem_finish(&ns);
+ } else {
+ ZDestroy(zs);
+ zs = NULL;
+ }
session_printf(s, "Calculating SHA1 checksum of file... ");
session_flush(s);
@@ -524,6 +578,7 @@ folder_file_view(struct session *s, struct folder *fol
struct folder_file file;
struct username_cache *uploader;
struct zmodem_session *zs;
+ struct nomodem_session *ns;
struct session_menu_option *dopts = NULL;
FILE *fp;
size_t size;
@@ -608,45 +663,68 @@ folder_file_view(struct session *s, struct folder *fol
break;
}
- zs = ZCreateSender(s, fp, file.filename);
- if (zs == NULL) {
- xfree(&path);
- done = true;
- break;
+ if (s->can_nomodem) {
+ ns = nomodem_send(s, fp, file.filename);
+ if (ns == NULL) {
+ xfree(&path);
+ done = true;
+ break;
+ }
+ } else {
+ zs = ZCreateSender(s, fp, file.filename);
+ if (zs == NULL) {
+ xfree(&path);
+ done = true;
+ break;
+ }
+ zs->DoIACEscape = s->is_telnet;
+ ZInit(zs);
+ s->direct_output = true;
}
- zs->DoIACEscape = s->is_telnet;
- ZInit(zs);
- s->transferring_file = true;
session_logf(s, "[%s] Downloading file %s", folder->name,
file.filename);
for (;;) {
- if (ZHaveTimedOut(zs)) {
- ZTimeOutProc(zs);
- session_logf(s, "[%s] Transfer timed out, canceling",
- folder->name);
- break;
+ if (s->can_nomodem) {
+ if (nomodem_timed_out(ns))
+ goto timed_out;
+ if (!nomodem_continue(ns))
+ break;
+ } else {
+ if (ZHaveTimedOut(zs)) {
+ ZTimeOutProc(zs);
+ goto timed_out;
+ }
+
+ if (!ZParse(zs))
+ break;
}
- if (!ZParse(zs))
- break;
-
if (s->obuflen)
session_flush(s);
+ continue;
+timed_out:
+ session_logf(s, "[%s] Transfer timed out, canceling",
+ folder->name);
+ break;
}
/* flush the pipes */
s->obuflen = 0;
uthread_msleep(1000);
session_clear_input(s);
- s->transferring_file = false;
- if (zs->file) {
- fclose(zs->file);
- zs->file = NULL;
+ if (s->can_nomodem) {
+ nomodem_finish(&ns);
+ } else {
+ s->direct_output = false;
+ if (zs->file) {
+ fclose(zs->file);
+ zs->file = NULL;
+ }
+ ZDestroy(zs);
+ zs = NULL;
}
- ZDestroy(zs);
- zs = NULL;
xfree(&path);
session_printf(s, "\r\n");
@@ -1190,4 +1268,4 @@ folder_file_checksum(struct session *s, struct folder_
return false;
return true;
-}
+}