update: recvfile and sendfile callbacks and more ctx function implementations
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user