update: recvfile and sendfile callbacks and more ctx function implementations

This commit is contained in:
ngn
2024-07-05 16:27:11 +03:00
parent 6045f73478
commit 98e5c861df
21 changed files with 1359 additions and 429 deletions

View File

@ -2,13 +2,15 @@
#include "../../include/error.h"
#include "../../include/util.h"
#include <sys/stat.h>
#include <errno.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path){
if (NULL == path){
bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path, lm_mptp_transfer_callback_t callback, void *data){
if (NULL == path || NULL == addr){
lm_error_set(LM_ERR_ArgNULL);
return false;
}
@ -17,7 +19,10 @@ bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path){
bool ret = false;
FILE *file = fopen(path, "r");
size_t total = 0, current = 0;
size_t read = 0;
struct stat st;
int size = -1;
if(NULL == file){
pdebug(__func__, "failed to open file: %s", path);
@ -25,16 +30,51 @@ bool lm_mptp_sendfile(int sock, struct sockaddr *addr, char *path){
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
}
if(fstat(fileno(file), &st)<0){
pdebug(__func__, "failed to stat file: %s", path);
lm_error_set(LM_ERR_SendStatFail);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
}
total = st.st_size;
lm_mptp_init(&packet, false, MPTP_S2C_COOL, false);
if((size = snprintf(packet.data, MPTP_DATA_MAX, "%lu", st.st_size)) <= 0){
pdebug(__func__, "snprintf for stat size failed: %s", path);
lm_error_set(LM_ERR_SendSnprintfFail);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
}
packet.header.data_size = size;
lm_mptp_server_send(sock, &packet, addr);
// clear the packet
lm_mptp_init(&packet, false, MPTP_S2C_COOL, false);
while ((read = fread(packet.data, 1, MPTP_DATA_MAX, file)) > 0) {
packet.header.data_size = read;
if(!lm_mptp_server_send(sock, &packet, addr))
goto end;
current += read;
if(NULL != callback)
if(!callback(path, current, st.st_size, data))
goto end;
lm_mptp_init(&packet, false, MPTP_S2C_COOL, false);
}
if(current != total){
pdebug(__func__, "failed read the entire file (left at %lu/%lu): %s", current, total, path);
lm_error_set(LM_ERR_SendReadFail);
lm_mptp_init(&packet, false, MPTP_S2C_BRUH, true);
goto end;
}
lm_mptp_init(&packet, false, MPTP_S2C_COOL, true);
ret = true;
@ -45,7 +85,7 @@ end:
return ret;
}
bool lm_mptp_recvfile(int sock, char *path){
bool lm_mptp_recvfile(int sock, char *path, lm_mptp_transfer_callback_t callback, void *data){
if(NULL == path){
lm_error_set(LM_ERR_ArgNULL);
return false;
@ -57,6 +97,7 @@ bool lm_mptp_recvfile(int sock, char *path){
}
FILE *file = fopen(path, "a");
size_t total = 0, current = 0;
bool ret = false;
lm_mptp_t packet;
@ -66,6 +107,23 @@ bool lm_mptp_recvfile(int sock, char *path){
goto end;
}
if(!lm_mptp_client_recv(sock, &packet) || !lm_mptp_client_verify(&packet))
goto end;
if(MPTP_FLAGS_CODE(&packet) != MPTP_S2C_COOL){
lm_error_set(LM_ERR_RecvBadCode);
goto end;
}
char buffer[MPTP_DATA_MAX+1];
lm_mptp_get_data(&packet, buffer);
total = atol(buffer);
if(total <= 0){
lm_error_set(LM_ERR_RecvBadSize);
goto end;
}
while(lm_mptp_client_recv(sock, &packet)){
if(!lm_mptp_client_verify(&packet))
goto end;
@ -82,6 +140,18 @@ bool lm_mptp_recvfile(int sock, char *path){
lm_error_set(LM_ERR_RecvWriteFail);
goto end;
}
current += packet.header.data_size;
if(NULL != callback)
if(!callback(path, current, total, data))
goto end;
}
if(current != total){
pdebug(__func__, "failed to receive the entire file (left at %lu/%lu): %s (%s)", current, total, path, lm_strerror());
lm_error_set(LM_ERR_RecvNotCompleted);
goto end;
}
ret = true;