File transfers working.

This commit is contained in:
Scott Duensing 2022-02-14 20:13:42 -06:00
parent 1a9fcdaaf3
commit d15b264ef6
13 changed files with 167 additions and 79 deletions

View file

@ -20,6 +20,7 @@
#include "network.h" #include "network.h"
#include "packet.h" #include "packet.h"
#include "array.h"
#include "taglist.h" #include "taglist.h"
#include "window.h" #include "window.h"
@ -28,12 +29,22 @@
#include "file.h" #include "file.h"
// All this queue nonsense allows you to request more
// downloads while downloads are currently running.
typedef struct FileListS {
char **files;
fileCallback callback;
} FileListT;
static uint8_t _channel = 0; static uint8_t _channel = 0;
static uint8_t _dialogVisible = 0; static uint8_t _dialogVisible = 0;
static int16_t _index = -1; static FileListT **_fileList = NULL;
static char **_fileList = NULL; static FileListT *_current = NULL;
static uint32_t _currentLength = 0;
static char *_currentSha256 = NULL;
static char *_file = NULL;
static FILE *_handle = NULL; static FILE *_handle = NULL;
static fileCallback _done = NULL;
static WindowT *_winFile = NULL; static WindowT *_winFile = NULL;
static LabelT *_lblFile = NULL; static LabelT *_lblFile = NULL;
@ -45,11 +56,24 @@ static void packetHandler(PacketDecodeDataT *packet);
void fileCacheCheck(fileCallback callback, char *vpaths[]) { void fileCacheCheck(fileCallback callback, char *vpaths[]) {
_done = callback; FileListT *newList = NULL;
_fileList = vpaths; uint16_t i = 0;
_index = -1;
_dialogVisible = 0; // Add new entries to anything already in the queue.
_channel = netChannelGet(packetHandler); NEW(FileListT, newList);
newList->callback = callback;
newList->files = NULL;
while (vpaths[i] != NULL) {
arrput(newList->files, strdup(vpaths[i]));
i++;
}
arrput(_fileList, newList);
// New queue?
if (_channel == 0) {
_dialogVisible = 0;
_channel = netChannelGet(packetHandler);
}
fileCheckNext(); fileCheckNext();
} }
@ -60,25 +84,57 @@ static void fileCheckNext(void) {
char *packetData = NULL; char *packetData = NULL;
uint16_t length = 0; uint16_t length = 0;
uint32_t temp = 0; uint32_t temp = 0;
uint8_t doRecheck = 0;
char *shaPointer = NULL; char *shaPointer = NULL;
static char *badSHA = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; static char *badSHA = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
_index++; do {
// This is ugly since both lists kind of depend on each other.
doRecheck = 0;
if (_fileList[_index] == NULL) { // Do we need a new entry from the queue?
// End of list! if (_current == NULL) {
if (_dialogVisible) guiDelete(D(_winFile)); // End of queue?
netChannelRelease(_channel); if (arrlen(_fileList) == 0) {
_done(); logWrite("End of queue.\n");
return; arrfree(_fileList);
} if (_dialogVisible) guiDelete(D(_winFile));
netChannelRelease(_channel);
return;
}
// Get next queue entry.
logWrite("Next queue entry.\n");
_currentLength = 0;
_current = _fileList[0];
arrdel(_fileList, 0);
}
if (_file) DEL(_file);
// End of current queue file list?
if (arrlen(_current->files) == 0) {
logWrite("End of files.\n");
// End of list!
arrfree(_current->files);
_current->callback();
DEL(_current);
// See if there's more.
doRecheck = 1;
} else {
// No. Get next file.
logWrite("Next file.\n");
_file = _current->files[0];
arrdel(_current->files, 0);
}
} while (doRecheck);
// Check next file. // Check next file.
temp = FILE_REQUEST_CHECK; temp = FILE_REQUEST_CHECK;
shaPointer = cacheSha256Get(_fileList[_index]); shaPointer = cacheSha256Get(_file);
if (!shaPointer) shaPointer = badSHA; if (!shaPointer) shaPointer = badSHA;
packetData = packetContentPack(&length, "iss", temp, shaPointer, _fileList[_index]); packetData = packetContentPack(&length, "iss", temp, shaPointer, _file);
logWrite("Checking [%d] [%s] [%s]\n", temp, shaPointer, _fileList[_index]); logWrite("Checking [%d] [%s] [%s]\n", temp, shaPointer, _file);
encoded.control = PACKET_CONTROL_DAT; encoded.control = PACKET_CONTROL_DAT;
encoded.packetType = PACKET_TYPE_FILE_REQUEST; encoded.packetType = PACKET_TYPE_FILE_REQUEST;
encoded.channel = _channel; encoded.channel = _channel;
@ -117,18 +173,14 @@ static void fileShowError(char *message) {
static void packetHandler(PacketDecodeDataT *packet) { static void packetHandler(PacketDecodeDataT *packet) {
FileResponseT response = 0; FileResponseT response = 0;
uint32_t fileLength = 0;
PacketEncodeDataT encoded = { 0 }; PacketEncodeDataT encoded = { 0 };
char *packetData = NULL; char *packetData = NULL;
uint16_t length = 0; uint16_t length = 0;
uint32_t temp = 0; uint32_t temp = 0;
logWrite("Got packet %d\n", packet->packetType);
if (packet->packetType == PACKET_TYPE_FILE_RESPONSE) { if (packet->packetType == PACKET_TYPE_FILE_RESPONSE) {
// Extract the response type. We get more data later. // Extract the response type. We get more data later.
packetContentUnpack(packet->data, "i", &response); packetContentUnpack(packet->data, "i", &response);
logWrite("Got response %d [%d bytes]\n", response, sizeof(response));
switch (response) { switch (response) {
case FILE_RESPONSE_UNKNOWN: case FILE_RESPONSE_UNKNOWN:
logWrite("Unknown file transfer response.\n"); logWrite("Unknown file transfer response.\n");
@ -142,36 +194,43 @@ static void packetHandler(PacketDecodeDataT *packet) {
break; break;
case FILE_RESPONSE_SEND: case FILE_RESPONSE_SEND:
// Get file size. // Start of new file. Get SHA and length.
logWrite("Got FILE_RESPONSE_SEND\n"); logWrite("Got FILE_RESPONSE_SEND\n");
packetContentUnpack(packet->data, "ii", &response, &fileLength); packetContentUnpack(packet->data, "iis", &response, &_currentLength, &_currentSha256);
break;
case FILE_RESPONSE_DATA:
// Get file size.
logWrite("Got FILE_RESPONSE_DATA\n");
// Receive new file data. // Receive new file data.
if (!_dialogVisible) fileShowDialog(); if (!_dialogVisible) fileShowDialog();
// Are we starting a new file? // Are we starting a new file?
if (_handle == NULL) { if (_handle == NULL) {
logWrite("Opening [%s]\n", _fileList[_index]); logWrite("Opening [%s]\n", _file);
_handle = cacheFOpen(_fileList[_index], "wb"); _handle = cacheFOpen(_file, "wb");
if (!_handle) { if (!_handle) {
fileShowError("Unable to write to cache."); fileShowError("Unable to write to cache.");
break; break;
} }
} }
// Write data to file, skipping first two integers stored in packet. // Write data to file, skipping first integer stored in packet.
logWrite("Writing %d bytes to [%s]\n", packet->length - 8, _fileList[_index]); logWrite("Writing %d bytes to [%s]\n", packet->length - 4, _file);
fwrite(&packet->data[8], packet->length - 8, 1, _handle); fwrite(&packet->data[4], packet->length - 4, 1, _handle);
// Is this file complete? // Is this file complete?
if (ftell(_handle) >= fileLength) { if (ftell(_handle) >= _currentLength) {
logWrite("Closing [%s]\n", _fileList[_index]); logWrite("Closing [%s]\n", _file);
// Close this file. // Close this file.
cacheFClose(_handle); cacheFClose(_handle);
_handle = NULL; _handle = NULL;
// Update cache entry to include SHA.
cacheEntryAdd(_currentSha256, cacheEntryNameGet(_file), _file);
// Next file! // Next file!
fileCheckNext(); fileCheckNext();
} else { } else {
logWrite("Sending FILE_REQUEST_NEXT\n"); logWrite("Sending FILE_REQUEST_NEXT\n");
// Tell the server we got this bit of data, send the next. // Tell the server we got this bit of data, send the next.
temp = FILE_REQUEST_NEXT; temp = FILE_REQUEST_NEXT;
packetData = packetContentPack(&length, "i", temp); packetData = packetContentPack(&length, "i", temp);
encoded.control = PACKET_CONTROL_DAT; encoded.control = PACKET_CONTROL_DAT;
encoded.packetType = PACKET_TYPE_FILE_REQUEST; encoded.packetType = PACKET_TYPE_FILE_REQUEST;
encoded.channel = _channel; encoded.channel = _channel;

View file

@ -96,7 +96,7 @@ static void timHangupProgress(WidgetT *widget) {
case S_WAITING: case S_WAITING:
// Shut down packet processing & COM port. // Shut down packet processing & COM port.
netShutdown(); netPacketHandlerStop();
comClose(__configData.serialCom - 1); comClose(__configData.serialCom - 1);
timerStop(t); timerStop(t);
// On to the next dialog. // On to the next dialog.

View file

@ -220,7 +220,7 @@ static void tableLoad(void) {
line = (char *)malloc(4096); line = (char *)malloc(4096);
if (line) { if (line) {
// Load string cache. // Load string cache.
cache = cacheFOpen("system:strings", "rt"); cache = cacheFOpen("data:strings.dat", "rt");
if (cache) { if (cache) {
while (fscanf(cache, "%s\n", line) != EOF) { while (fscanf(cache, "%s\n", line) != EOF) {
p = strstr(line, "="); p = strstr(line, "=");
@ -239,7 +239,7 @@ static void tableLoad(void) {
cacheFClose(cache); cacheFClose(cache);
} }
// Load integer cache. // Load integer cache.
cache = cacheFOpen("system:integers", "rt"); cache = cacheFOpen("data:integers.dat", "rt");
if (cache) { if (cache) {
while (fscanf(cache, "%s\n", line) != EOF) { while (fscanf(cache, "%s\n", line) != EOF) {
p = strstr(line, "="); p = strstr(line, "=");
@ -262,7 +262,7 @@ static void tableSave(void) {
FILE *cache = NULL; FILE *cache = NULL;
// Save & free integer table. // Save & free integer table.
cache = cacheFOpen("system:integers", "wt"); cache = cacheFOpen("data:integers.dat", "wt");
if (cache) { if (cache) {
if (__runtimeData.integers) { if (__runtimeData.integers) {
while (shlen(__runtimeData.integers) > 0) { while (shlen(__runtimeData.integers) > 0) {
@ -276,7 +276,7 @@ static void tableSave(void) {
} }
// Save & free string table. // Save & free string table.
cache = cacheFOpen("system:strings", "wt"); cache = cacheFOpen("data:strings.dat", "wt");
if (cache) { if (cache) {
if (__runtimeData.strings) { if (__runtimeData.strings) {
while (shlen(__runtimeData.strings) > 0) { while (shlen(__runtimeData.strings) > 0) {

View file

@ -53,7 +53,7 @@ static void btnLogoffClick(WidgetT *widget) {
(void)widget; (void)widget;
setButtons(0); setButtons(0);
msgBoxTwo("Cancel?", MSGBOX_ICON_QUESTION, "Cancel login?\n \nThis will disconnect you from the server.", "Okay", btnMsgBoxLogoff, "Cancel", btnMsgBoxLogoff); msgBoxTwo("Logoff?", MSGBOX_ICON_QUESTION, "This will disconnect you from the server.", "Okay", btnMsgBoxLogoff, "Cancel", btnMsgBoxLogoff);
} }

View file

@ -115,6 +115,8 @@ uint8_t cacheEntryAdd(char *sha256, char *entryName, char *virtualPath) {
// Index format is: SHA256 ENTRYNAME VIRTUALPATH // Index format is: SHA256 ENTRYNAME VIRTUALPATH
logWrite("Adding SHA [%s] Entry [%s] VPath [%s]\n", sha256, entryName, virtualPath);
sprintf(index, "CACHE%cINDEX.DAT", OS_PATH_SLASH); sprintf(index, "CACHE%cINDEX.DAT", OS_PATH_SLASH);
sprintf(indexNew, "CACHE%cINDEX.NEW", OS_PATH_SLASH); sprintf(indexNew, "CACHE%cINDEX.NEW", OS_PATH_SLASH);
@ -243,7 +245,7 @@ void cacheFClose(FILE *handle) {
static char *cacheFieldGet(char *virtualPath, uint8_t field) { static char *cacheFieldGet(char *virtualPath, uint8_t field) {
FILE *in = NULL; FILE *in = NULL;
char index[16] = { 0 }; char index[16] = { 0 };
static char buffer[1024] = { 0 }; static char buffer[2048] = { 0 };
static char *name = NULL; static char *name = NULL;
static char *path = NULL; static char *path = NULL;
static char *result = NULL; static char *result = NULL;
@ -258,7 +260,7 @@ static char *cacheFieldGet(char *virtualPath, uint8_t field) {
if (osFileExists(index)) { if (osFileExists(index)) {
in = fopen(index, "rt"); in = fopen(index, "rt");
if (in) { if (in) {
while ((fgets(buffer, 1024, in) != 0) && result == NULL) { while (result == NULL && (fgets(buffer, 2048, in) != 0)) {
name = strstr(buffer, " "); name = strstr(buffer, " ");
*name = 0; *name = 0;
name++; name++;

View file

@ -21,8 +21,8 @@ TEMPLATE = subdirs
CONFIG *= ORDERED CONFIG *= ORDERED
SUBDIRS = \ SUBDIRS = \
client \ client
server # server
# precache # precache
# font # font
# primes # primes

View file

@ -44,13 +44,13 @@ DROP TABLE IF EXISTS `files`;
CREATE TABLE `files` ( CREATE TABLE `files` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`realPath` varchar(1024) NOT NULL, `realPath` varchar(1024) NOT NULL,
`virtualPath` varchar(1024) NOT NULL, `virtualPath` varchar(512) NOT NULL,
`sha256` varchar(64) NOT NULL, `sha256` varchar(64) NOT NULL,
`description` varchar(255) NOT NULL, `description` varchar(255) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `virtualPath` (`virtualPath`), UNIQUE KEY `virtualPath` (`virtualPath`),
UNIQUE KEY `realPath` (`realPath`) UNIQUE KEY `realPath` (`realPath`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1; ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
@ -99,14 +99,14 @@ CREATE TABLE `users` (
`first` varchar(64) NOT NULL, `first` varchar(64) NOT NULL,
`last` varchar(64) NOT NULL, `last` varchar(64) NOT NULL,
`user` varchar(64) NOT NULL, `user` varchar(64) NOT NULL,
`pass` varchar(64) NOT NULL, `pass` varchar(128) NOT NULL,
`email` varchar(256) NOT NULL, `email` varchar(256) NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT 0, `enabled` tinyint(1) NOT NULL DEFAULT 0,
`notes` text NOT NULL, `notes` text NOT NULL DEFAULT '',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `emailIDX` (`email`), UNIQUE KEY `emailIDX` (`email`),
UNIQUE KEY `userIDX` (`user`) USING BTREE UNIQUE KEY `userIDX` (`user`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -118,4 +118,4 @@ CREATE TABLE `users` (
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2022-02-09 15:58:23 -- Dump completed on 2022-02-14 20:13:22

View file

@ -179,8 +179,12 @@ void *clientThread(void *data) {
arrdel(client->packetQueue, 0); arrdel(client->packetQueue, 0);
} }
arrfree(client->packetQueue); arrfree(client->packetQueue);
pthread_mutex_destroy(&client->packetQueueMutex); pthread_mutex_destroy(&client->packetQueueMutex);
packetThreadDataDestroy(&client->packetThreadData); packetThreadDataDestroy(&client->packetThreadData);
if (client->handle) fclose(client->handle);
DEL(client); DEL(client);
pthread_exit(NULL); pthread_exit(NULL);

View file

@ -51,9 +51,9 @@ typedef struct ClientThreadS {
double pingLow; double pingLow;
void *peer; void *peer;
// User State Stuff. // User State Stuff.
uint8_t authenticated; uint8_t authenticated; // Is the user logged in?
FILE *handle; // ***TODO*** Needs to support more than one file transfer at a time. FILE *handle; // Handle of file currently being transferred to client.
uint32_t fileSize; // Length of current file being transferred. uint32_t fileSize; // Length of current file being transferred.
} ClientThreadT; } ClientThreadT;

View file

@ -75,23 +75,30 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT *
PacketEncodeDataT encoded = { 0 }; PacketEncodeDataT encoded = { 0 };
char *packetData = NULL; char *packetData = NULL;
uint16_t length = 0; uint16_t length = 0;
char shaInDB[128] = { 0 };
char buffer[1024] = { 0 }; char buffer[1024] = { 0 };
char buffer2[1024] = { 0 }; char buffer2[2048] = { 0 };
uint32_t temp = 0; uint32_t temp = 0;
logWrite("Got FILE_REQUEST_CHECK\n\r"); logWrite("Got FILE_REQUEST_CHECK\n\r");
// Is something still open?
if (client->handle) {
fclose(client->handle);
client->handle = NULL;
}
// Extract the request. // Extract the request.
packetContentUnpack(data->data, "iss", &request, &sha256, &path); packetContentUnpack(data->data, "iss", &request, &sha256, &path);
logWrite("[%s] [%s]\n\r", sha256, path); logWrite("[%s] [%s]\n\r", sha256, path);
// Look up the entry and compare SHA256. // Look up the entry and compare SHA256.
dbFileSha256Get(path, buffer, FILE_VIRTUAL_PATH_MAX); dbFileSha256Get(path, shaInDB, FILE_VIRTUAL_PATH_MAX);
if (strcasecmp(sha256, buffer) == 0) { if (strcasecmp(sha256, shaInDB) == 0) {
logWrite("File is current. Sending FILE_RESPONSE_OKAY.\n\r"); logWrite("File is current. Sending FILE_RESPONSE_OKAY.\n\r");
// File is already current on client. // File is already current on client.
temp = FILE_RESPONSE_OKAY; temp = FILE_RESPONSE_OKAY;
packetData = packetContentPack(&length, "i", temp); packetData = packetContentPack(&length, "i", temp);
encoded.control = PACKET_CONTROL_DAT; encoded.control = PACKET_CONTROL_DAT;
encoded.packetType = PACKET_TYPE_FILE_RESPONSE; encoded.packetType = PACKET_TYPE_FILE_RESPONSE;
encoded.channel = data->channel; encoded.channel = data->channel;
@ -103,21 +110,32 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT *
logWrite("File needs updated.\n\r"); logWrite("File needs updated.\n\r");
// Get real path. // Get real path.
dbFileRealPathGet(path, buffer, FILE_VIRTUAL_PATH_MAX); dbFileRealPathGet(path, buffer, FILE_VIRTUAL_PATH_MAX);
snprintf(buffer2, 1024, "%s%s", __settingsFile, buffer); snprintf(buffer2, 2048, "%s%s", __settingsFile, buffer);
// Open file & get file size. // Open file & get file size.
client->handle = fopen(buffer2, "rb"); client->handle = fopen(buffer2, "rb");
if (!client->handle) { if (!client->handle) {
logWrite("Unable to open [%s]\n", buffer2);
// ***TODO*** Handle error // ***TODO*** Handle error
return;
} }
fseek(client->handle, 0, SEEK_END); fseek(client->handle, 0, SEEK_END);
client->fileSize = ftell(client->handle); client->fileSize = ftell(client->handle);
fseek(client->handle, 0, SEEK_SET); fseek(client->handle, 0, SEEK_SET);
// Start sending new file to client.
packetData = (char *)malloc(PACKET_MAX);
if (!packetData) {
// ***TODO*** Handle error
}
logWrite("Size is %d\n\r", client->fileSize); logWrite("Size is %d\n\r", client->fileSize);
// Send file metadata to start transfer
logWrite("Sending FILE_RESPONSE_SEND.\n\r");
temp = FILE_RESPONSE_SEND;
packetData = packetContentPack(&length, "iis", temp, client->fileSize, shaInDB);
encoded.control = PACKET_CONTROL_DAT;
encoded.packetType = PACKET_TYPE_FILE_RESPONSE;
encoded.channel = data->channel;
encoded.encrypt = 0;
packetEncode(client->packetThreadData, &encoded, packetData, length);
packetSend(client->packetThreadData, &encoded);
DEL(packetData);
// Start sending actual file data.
clientApiFileRequestNext(client, data); clientApiFileRequestNext(client, data);
} }
} }
@ -127,39 +145,36 @@ static void clientApiFileRequestNext(ClientThreadT *client, PacketDecodeDataT *d
uint32_t temp = 0; uint32_t temp = 0;
PacketEncodeDataT encoded = { 0 }; PacketEncodeDataT encoded = { 0 };
uint16_t length = 0; uint16_t length = 0;
uint16_t dataSize = 0;
char packetData[PACKET_MAX]; char packetData[PACKET_MAX];
// Do we have an open file? // Do we have an open file?
if (client->handle) { if (client->handle) {
logWrite("Sending FILE_RESPONSE_SEND.\n\r"); logWrite("Sending FILE_RESPONSE_DATA.\n\r");
// Add response type. // Add response type.
temp = FILE_RESPONSE_SEND; temp = FILE_RESPONSE_DATA;
memcpy(packetData, &temp, sizeof(int32_t)); memcpy(&packetData[0], &temp, sizeof(int32_t));
// Add file length.
memcpy(&packetData[4], &client->fileSize, sizeof(int32_t));
// Add file data. // Add file data.
dataSize = client->fileSize - ftell(client->handle); // ***TODO*** We can't send quite a full packet for some reason.
if (dataSize > PACKET_MAX - 8) { length = client->fileSize - ftell(client->handle);
if (length > PACKET_MAX - 14) {
// File is larger than a packet size. // File is larger than a packet size.
dataSize = PACKET_MAX - 8; // 8 for two integers of response data. length = PACKET_MAX - 14; // 4 for integer of response type. 10 more because a full PACKET_MAX causes issues.
fread(&packetData[8], dataSize, 1, client->handle); fread(&packetData[4], length, 1, client->handle);
} else { } else {
// File remains will fit in this packet. // File remains will fit in this packet.
fread(&packetData[8], dataSize, 1, client->handle); fread(&packetData[4], length, 1, client->handle);
fclose(client->handle); fclose(client->handle);
client->handle = NULL; client->handle = NULL;
} }
logWrite("Sending %d bytes\n\r", dataSize); logWrite("Sending %d bytes of file\n\r", length);
// Build packet. // Build packet.
encoded.control = PACKET_CONTROL_DAT; encoded.control = PACKET_CONTROL_DAT;
encoded.packetType = PACKET_TYPE_FILE_RESPONSE; encoded.packetType = PACKET_TYPE_FILE_RESPONSE;
encoded.channel = data->channel; encoded.channel = data->channel;
encoded.encrypt = 0; encoded.encrypt = 0;
packetEncode(client->packetThreadData, &encoded, packetData, length); packetEncode(client->packetThreadData, &encoded, packetData, length + 4);
// Send it. // Send it.
packetSend(client->packetThreadData, &encoded); packetSend(client->packetThreadData, &encoded);
} }

View file

@ -26,6 +26,9 @@
#include "database.h" #include "database.h"
// ***TODO*** Left/Right trim whitespace from returned strings?
#define STATEMENT_MAX 2048 #define STATEMENT_MAX 2048

View file

@ -153,6 +153,8 @@ void *serverThread(void *data) {
client->pingLow = 9999; client->pingLow = 9999;
// User State Stuff. // User State Stuff.
client->authenticated = 0; client->authenticated = 0;
client->handle = NULL;
client->fileSize = 0;
// Keep our client in the peer data for later. // Keep our client in the peer data for later.
event.peer->data = (void *)client; event.peer->data = (void *)client;
// Make new thread for this client. // Make new thread for this client.

View file

@ -64,7 +64,9 @@ typedef enum PacketTypeE {
* Client -> PACKET_TYPE_FILE_REQUEST FILE_REQUEST_CHECK SHA256 VPATH * Client -> PACKET_TYPE_FILE_REQUEST FILE_REQUEST_CHECK SHA256 VPATH
* Server -> PACKET_TYPE_FILE_RESPONSE FILE_RESPONSE_OKAY * Server -> PACKET_TYPE_FILE_RESPONSE FILE_RESPONSE_OKAY
* - or - * - or -
* Server -> PACKET_TYPE_FILE_RESPONSE FILE_RESPONSE_SEND (4 bytes length) (data...) * Server -> PACKET_TYPE_FILE_RESPONSE FILE_RESPONSE_SEND (4 bytes length) SHA256
*
* Server -> PACKET_TYPE_FILE_RESPONSE FILE_RESPONSE_DATA (data...)
* Client -> PACKET_TYPE_FILE_REQUEST FILE_REQUEST_NEXT * Client -> PACKET_TYPE_FILE_REQUEST FILE_REQUEST_NEXT
* (Repeat until received data matches the length.) * (Repeat until received data matches the length.)
*/ */
@ -76,6 +78,7 @@ typedef enum FileRequestsE {
typedef enum FileResponseE { typedef enum FileResponseE {
FILE_RESPONSE_UNKNOWN = 0, FILE_RESPONSE_UNKNOWN = 0,
FILE_RESPONSE_DATA,
FILE_RESPONSE_OKAY, FILE_RESPONSE_OKAY,
FILE_RESPONSE_SEND FILE_RESPONSE_SEND
} FileResponseT; } FileResponseT;