From 111a81618f6153419655900ec607b5e91c5fef01 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Mon, 18 May 2026 18:35:59 +0300 Subject: [PATCH] experimental cancel of upload --- src/file_p.c | 75 ++++++++++++++++++++++++++++++++++++++++----------- src/file_p.h | 20 ++++++++------ src/main.h | 13 +++++++++ src/session.c | 4 +-- 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/src/file_p.c b/src/file_p.c index 5d56c45..6d0678e 100644 --- a/src/file_p.c +++ b/src/file_p.c @@ -197,6 +197,7 @@ int file_receive_prepare(session *sess, char *line, server_data_t *s_d) { sess->file->path = malloc(sizeof(STORAGE_FOLDER) + 2 + 9); sess->file->permissions = (char)perm; sess->file->description = NULL; + sess->file->package_rest = 0; strncpy(sess->file->name, name_begin, name_len); sess->file->name[name_len] = 0; @@ -286,19 +287,15 @@ void clear_file_from_sess(session *s) { s->file = NULL; } -void file_load(session *sess, enum f_actions f_action) { - int source_d = f_action == F_DOWNLOAD ? sess->fd : sess->sd; - int dest_d = f_action == F_DOWNLOAD ? sess->sd : sess->fd; +/* download to the client */ +void file_download(session *sess) { + int source_d = sess->fd; + int dest_d = sess->sd; char buf[INBUFSIZE]; int rlen = read(source_d, buf, INBUFSIZE); if (rlen == 0) { if (sess->file->rest) { - if (f_action == F_DOWNLOAD) { - fprintf(stderr, "Error downloading file %s!\n", sess->file->name); - } else { - fprintf(stderr, "Error uploading file %s!\n", sess->file->name); - unlink(sess->file->path); /* remove file */ - } + fprintf(stderr, "Error downloading file %s!\n", sess->file->name); clear_file_from_sess(sess); } sess->state = OP_WAIT; @@ -307,15 +304,61 @@ void file_load(session *sess, enum f_actions f_action) { write(dest_d, buf, rlen); sess->file->rest -= rlen; if (!sess->file->rest) { - if (f_action == F_DOWNLOAD) { - printf("File %s is downloaded from the server\n", sess->file->name); + printf("File %s is downloaded from the server\n", sess->file->name); + clear_file_from_sess(sess); + sess->state = OP_WAIT; + } +} + +/* upload to the server */ +void file_upload(session *sess) { + int source_d = sess->sd; + int dest_d = sess->fd; + char buf[INBUFSIZE]; + int rlen = read(source_d, buf, INBUFSIZE); + if (rlen == 0) { + if (sess->file->rest) { + fprintf(stderr, "Error uploading file %s!\n", sess->file->name); + unlink(sess->file->path); /* remove file */ clear_file_from_sess(sess); - } else { - printf("File %s is uploaded to the server\n", sess->file->name); - session_send_string(sess, "finished\n"); - if (db_save_file(sess)) { - clear_file_from_sess(sess); + } + sess->state = OP_WAIT; + return; + } + if (sess->file->package_rest < rlen) { + write(dest_d, buf, sess->file->package_rest); + s_file_pd_t *fpd = (s_file_pd_t *)buf + sess->file->package_rest; + switch (fpd->signal) { + case sig_continue: + sess->file->package_rest = fpd->package_size; + rlen -= sizeof(s_file_pd_t); + if (rlen > 0) { + write(dest_d, buf + sizeof(s_file_pd_t), rlen); } + break; + case sig_cancel: + fprintf(stderr, "Upload of %s is cancelled!\n", sess->file->name); + unlink(sess->file->path); /* remove file */ + clear_file_from_sess(sess); + sess->state = OP_WAIT; + return; + case sig_finish: + /* TODO: implement */ + case sig_pause: + /* TODO: implement */ + break; + } + } else { + write(dest_d, buf, rlen); + } + + sess->file->rest -= rlen; + sess->file->package_rest -= rlen; + if (!sess->file->rest) { + printf("File %s is uploaded to the server\n", sess->file->name); + session_send_string(sess, "finished\n"); + if (db_save_file(sess)) { + clear_file_from_sess(sess); } sess->state = OP_WAIT; } diff --git a/src/file_p.h b/src/file_p.h index 6134e4e..2033e40 100644 --- a/src/file_p.h +++ b/src/file_p.h @@ -5,22 +5,26 @@ #define FILEP_H #include "main.h" #include -void clear_list(fl_t *start); + typedef struct { int32_t page; int32_t limit; char *name; } i_file_list_t; -void file_list(session *, server_data_t *, i_file_list_t *l_args); -int file_send_prepare(session *, char *, server_data_t *); + enum f_actions { F_UPLOAD, F_DOWNLOAD, }; -void file_load(session *sess, enum f_actions); -int file_receive_prepare(session *sess, char *line, server_data_t *s_d); -int file_upload_description(session *sess, char *line, server_data_t *s_d); -int file_save_db(session *sess, server_data_t *s_d); + +void clear_list(fl_t *start); +void file_list(session *, server_data_t *, i_file_list_t *l_args); +int file_send_prepare(session *, char *, server_data_t *); +int file_receive_prepare(session *sess, char *line, server_data_t *s_d); +int file_upload_description(session *sess, char *line, server_data_t *s_d); +int file_save_db(session *sess, server_data_t *s_d); void clear_file_from_sess(session *); -int directory_exists(const char *path); +int directory_exists(const char *path); +void file_download(session *sess); +void file_upload(session *sess); #endif \ No newline at end of file diff --git a/src/main.h b/src/main.h index 6e1dc94..ead3e55 100644 --- a/src/main.h +++ b/src/main.h @@ -54,11 +54,24 @@ typedef struct { char permissions; size_t size; size_t rest; + size_t package_rest; int32_t hash; int32_t id; int32_t owner_id; } s_file_t; +enum package_signal { + sig_continue, + sig_cancel, + sig_finish, + sig_pause +}; + +typedef struct { + enum package_signal signal; + size_t package_size; +} s_file_pd_t; /* file package descriptor */ + typedef struct fl_t { char *name; char *description; diff --git a/src/session.c b/src/session.c index 5505e92..461ba90 100644 --- a/src/session.c +++ b/src/session.c @@ -149,10 +149,10 @@ void perform_session_action(session *sess, char *line, server_data_t *s_d) { process_client_command(line, sess, s_d); break; case OP_DOWNLOAD: - file_load(sess, F_DOWNLOAD); + file_download(sess); break; case OP_UPLOAD: - file_load(sess, F_UPLOAD); + file_upload(sess); break; case OP_UPLOAD_DESCRIPTION: res = file_upload_description(sess, line, s_d);