From 027305c2447b05de2c576e3f5ee32ced400f439f Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 28 Feb 2017 19:58:57 +0100 Subject: Defined abstract packed buffers to transfert data. --- ChangeLog | 30 ++++ src/analysis/binary.c | 24 +++- src/analysis/db/cdb.c | 92 ++++++++---- src/analysis/db/client.c | 99 ++++++++----- src/analysis/db/collection.c | 55 +++---- src/analysis/db/collection.h | 9 +- src/analysis/db/item-int.h | 8 +- src/analysis/db/item.c | 79 +++++------ src/analysis/db/item.h | 5 +- src/analysis/db/items/bookmark.c | 48 +++---- src/analysis/db/items/comment.c | 92 ++++++------ src/analysis/db/items/move.c | 53 ++++--- src/analysis/db/items/switcher.c | 74 +++++----- src/analysis/db/misc/rlestr.c | 56 +++----- src/analysis/db/misc/rlestr.h | 5 +- src/analysis/db/misc/timestamp.c | 31 ++-- src/analysis/db/misc/timestamp.h | 5 +- src/analysis/db/server.c | 50 +++++-- src/arch/vmpa.c | 44 +++--- src/arch/vmpa.h | 5 +- src/common/Makefile.am | 1 + src/common/packed.c | 300 +++++++++++++++++++++++++++++++++++++++ src/common/packed.h | 72 ++++++++++ 23 files changed, 856 insertions(+), 381 deletions(-) create mode 100644 src/common/packed.c create mode 100644 src/common/packed.h diff --git a/ChangeLog b/ChangeLog index 7a15588..09e5a32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +17-02-28 Cyrille Bagard + + * src/analysis/binary.c: + * src/analysis/db/cdb.c: + * src/analysis/db/client.c: + * src/analysis/db/collection.c: + * src/analysis/db/collection.h: + * src/analysis/db/item-int.h: + * src/analysis/db/item.c: + * src/analysis/db/item.h: + * src/analysis/db/items/bookmark.c: + * src/analysis/db/items/comment.c: + * src/analysis/db/items/move.c: + * src/analysis/db/items/switcher.c: + * src/analysis/db/misc/rlestr.c: + * src/analysis/db/misc/rlestr.h: + * src/analysis/db/misc/timestamp.c: + * src/analysis/db/misc/timestamp.h: + * src/analysis/db/server.c: + * src/arch/vmpa.c: + * src/arch/vmpa.h: + Update code. + + * src/common/Makefile.am: + Add the 'packed.[ch]' files to libcommon_la_SOURCES. + + * src/common/packed.c: + * src/common/packed.h: + New entries: define abstract packed buffers to transfert data. + 17-02-25 Cyrille Bagard * src/gui/panels/welcome.c: diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 8c03dcf..603c519 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -1250,6 +1250,7 @@ bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bo GDbCollection *collec; /* Collection visée au final */ DBStorage storage; /* Forme d'enregistrement */ GDbClient *client; /* Liaison à utiliser */ + packed_buffer out_pbuf; /* Tampon d'émission */ int fd; /* Identifiant du canal de com.*/ feature = g_db_item_get_feature(item); @@ -1271,12 +1272,21 @@ bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bo client = binary->local; + init_packed_buffer(&out_pbuf); + fd = g_db_client_get_fd(client); - result = g_db_collection_send(collec, fd, DBA_ADD_ITEM, item); + result = g_db_collection_pack(collec, &out_pbuf, DBA_ADD_ITEM, item); g_db_client_put_fd(client); + if (result) + result = send_packed_buffer(&out_pbuf, fd); + + exit_packed_buffer(&out_pbuf); + + + } g_object_unref(G_OBJECT(collec)); @@ -1312,6 +1322,7 @@ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *binary, DBFeatures f GDbCollection *collec; /* Collection visée au final */ DBStorage storage; /* Forme d'enregistrement */ GDbClient *client; /* Liaison à utiliser */ + packed_buffer out_pbuf; /* Tampon d'émission */ int fd; /* Identifiant du canal de com.*/ collec = g_loaded_binary_find_collection(binary, feature); @@ -1331,12 +1342,21 @@ bool _g_loaded_binary_remove_from_collection(GLoadedBinary *binary, DBFeatures f client = binary->local; + init_packed_buffer(&out_pbuf); + fd = g_db_client_get_fd(client); - result = g_db_collection_send(collec, fd, DBA_REM_ITEM, item); + result = g_db_collection_pack(collec, &out_pbuf, DBA_REM_ITEM, item); g_db_client_put_fd(client); + if (result) + result = send_packed_buffer(&out_pbuf, fd); + + exit_packed_buffer(&out_pbuf); + + + } g_object_unref(G_OBJECT(collec)); diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index 75a8714..167fa0c 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -803,28 +803,38 @@ static bool g_cdb_archive_load_collections(GCdbArchive *archive) static void on_collection_changed(GDbCollection *collec, DBAction action, GDbItem *item, GCdbArchive *archive) { + packed_buffer pbuf; /* Tampon d'émission */ size_t i; /* Boucle de parcours */ bool status; /* Bilan d'un envoi de retour */ - g_mutex_lock(&archive->clients_access); + init_packed_buffer(&pbuf); - for (i = 0; i < archive->count; i++) - { - status = g_db_collection_send(collec, archive->clients[i].fd, action, item); + status = true; - if (!status) - { - /* TODO : close() */ - } + g_mutex_lock(&archive->clients_access); - } + for (i = 0; i < archive->count && status; i++) + status = g_db_collection_pack(collec, &pbuf, action, item); g_mutex_unlock(&archive->clients_access); + if (status) + status = send_packed_buffer(&pbuf, archive->clients[i].fd); + + exit_packed_buffer(&pbuf); + + if (!status) + goto occ_error; + + printf("CHANGED for %d clients !!\n", (int)archive->count); + occ_error: + + /* TODO : close() */ + ; } @@ -847,10 +857,12 @@ static void *g_cdb_archive_process(GCdbArchive *archive) nfds_t nfds; /* Quantité de ces flux */ nfds_t i; /* Boucle de parcours */ int ret; /* Bilan d'un appel */ - uint32_t val32; /* Valeur sur 32 bits */ + packed_buffer in_pbuf; /* Tampon de réception */ + uint32_t tmp32; /* Valeur sur 32 bits */ bool status; /* Bilan de lecture initiale */ uint32_t command; /* Commande de la requête */ DBError error; /* Bilan d'une opération */ + packed_buffer out_pbuf; /* Tampon d'émission */ GDbCollection *collec; /* Collection visée au final */ void interrupt_poll_with_sigusr1(int sig) { }; @@ -907,10 +919,13 @@ static void *g_cdb_archive_process(GCdbArchive *archive) /* Données présentes en entrée */ if (fds[i].revents & (POLLIN | POLLPRI)) { - status = safe_recv(fds[i].fd, &val32, sizeof(uint32_t), 0); + status = recv_packed_buffer(&in_pbuf, fds[i].fd); if (!status) goto gcap_bad_exchange; - command = be32toh(val32); + status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true); + if (!status) goto gcap_bad_exchange; + + command = tmp32; switch (command) { @@ -918,23 +933,31 @@ static void *g_cdb_archive_process(GCdbArchive *archive) error = g_cdb_archive_write(archive); - if (!safe_send(fds[i].fd, (uint32_t []) { htobe32(DBC_SAVE) }, sizeof(uint32_t), 0)) - goto gcap_bad_exchange; + init_packed_buffer(&out_pbuf); + + status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SAVE }, + sizeof(uint32_t), true); + if (!status) goto gcap_bad_reply; + + status = extend_packed_buffer(&out_pbuf, (uint32_t []) { error }, sizeof(uint32_t), true); + if (!status) goto gcap_bad_reply; - if (!safe_send(fds[i].fd, (uint32_t []) { htobe32(error) }, sizeof(uint32_t), 0)) - goto gcap_bad_exchange; + status = send_packed_buffer(&out_pbuf, fds[i].fd); + if (!status) goto gcap_bad_reply; + + exit_packed_buffer(&out_pbuf); break; case DBC_COLLECTION: - status = safe_recv(fds[i].fd, &val32, sizeof(uint32_t), 0); + status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true); if (!status) goto gcap_bad_exchange; - collec = find_collection_in_list(archive->collections, be32toh(val32)); + collec = find_collection_in_list(archive->collections, tmp32); if (collec == NULL) goto gcap_bad_exchange; - status = g_db_collection_recv(collec, fds[i].fd, archive->db); + status = g_db_collection_unpack(collec, &in_pbuf, archive->db); if (!status) goto gcap_bad_exchange; printf("## CDB ## Got something for collection %p...\n", collec); @@ -947,7 +970,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive) case DBC_SET_LAST_ACTIVE: - status = update_activity_in_collections(archive->collections, fds[i].fd, archive->db); + status = update_activity_in_collections(archive->collections, &in_pbuf, archive->db); if (!status) goto gcap_bad_exchange; break; @@ -959,12 +982,20 @@ static void *g_cdb_archive_process(GCdbArchive *archive) } + exit_packed_buffer(&in_pbuf); + continue; + gcap_bad_reply: + + exit_packed_buffer(&out_pbuf); + gcap_bad_exchange: printf("Bad exchange...\n"); + exit_packed_buffer(&in_pbuf); + /* TODO : close conn */ ; @@ -1018,6 +1049,8 @@ DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string GDbCollection *collec; /* Collection visée manipulée */ volatile pthread_t *process_id; /* Identifiant de la procédure */ + packed_buffer out_pbuf; /* Tampon d'émission */ + bool status; /* Bilan d'un envoi de retour */ @@ -1056,20 +1089,27 @@ DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string /* Envoi des mises à jour au nouveau client... */ + init_packed_buffer(&out_pbuf); + + status = true; + + + /* TODO : lock ? */ + for (iter = g_list_first(archive->collections); - iter != NULL; + iter != NULL && status; iter = g_list_next(iter)) { collec = G_DB_COLLECTION(iter->data); - if (!g_db_collection_send_all_updates(collec, fd)) - /* TODO */; - - + status = g_db_collection_pack_all_updates(collec, &out_pbuf); + } + if (status) + status = send_packed_buffer(&out_pbuf, fd); - } + exit_packed_buffer(&out_pbuf); diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c index 2a7aa03..309d9ed 100644 --- a/src/analysis/db/client.c +++ b/src/analysis/db/client.c @@ -353,11 +353,14 @@ bool g_db_client_start_remote(GDbClient *client, const char *host, unsigned shor static bool g_db_client_start_common(GDbClient *client, const char *desc) { + packed_buffer out_pbuf; /* Tampon d'émission */ + bool status; /* Bilan d'une opération */ rle_string user; /* Nom d'utilisateur associé */ GChecksum *checksum; /* Empreinte MD5 à signer */ unsigned char md5_digest[16]; /* Empreinte MD5 calculée */ RSA *key; /* Clef pour la signature */ unsigned char sig[RSA_USED_SIZE]; /* Signature effectuée */ + packed_buffer in_pbuf; /* Tampon de réception */ uint32_t data; /* Mot de données lues */ DBError error; /* Validation de la connexion */ @@ -372,19 +375,21 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc) * Tout ceci est à synchroniser avec la fonction g_db_server_listener(). */ - if (!safe_send(client->fd, (uint32_t []) { htobe32(DBC_HELO) }, sizeof(uint32_t), MSG_MORE)) - goto gdcs_error; + init_packed_buffer(&out_pbuf); - if (!safe_send(client->fd, (uint32_t []) { htobe32(CDB_PROTOCOL_VERSION) }, sizeof(uint32_t), MSG_MORE)) - goto gdcs_error; + status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_HELO }, sizeof(uint32_t), true); + if (!status) goto gdcs_error; - if (!send_rle_string(&client->hash, client->fd, MSG_MORE)) - goto gdcs_error; + status = extend_packed_buffer(&out_pbuf, (uint32_t []) { CDB_PROTOCOL_VERSION }, sizeof(uint32_t), true); + if (!status) goto gdcs_error; + + status = pack_rle_string(&client->hash, &out_pbuf); + if (!status) goto gdcs_error; init_rle_string(&user, client->author); - if (!send_rle_string(&user, client->fd, MSG_MORE)) - goto gdcs_error; + status = pack_rle_string(&user, &out_pbuf); + if (!status) goto gdcs_error; checksum = g_checksum_new(G_CHECKSUM_MD5); g_checksum_update(checksum, (guchar *)get_rle_string(&user), get_rle_length(&user)); @@ -399,8 +404,11 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc) RSA_free(key); - if (!safe_send(client->fd, sig, RSA_USED_SIZE, 0)) - goto gdcs_error; + status = extend_packed_buffer(&out_pbuf, sig, RSA_USED_SIZE, false); + if (!status) goto gdcs_error; + + status = send_packed_buffer(&out_pbuf, client->fd); + if (!status) goto gdcs_error; /** * Le serveur doit répondre pour un message type : @@ -409,19 +417,22 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc) * ou 'DBE_WRONG_VERSION' ... 'DBE_LOADING_ERROR'). */ - if (!safe_recv(client->fd, &data, sizeof(uint32_t), 0)) - goto gdcs_error; + status = recv_packed_buffer(&in_pbuf, client->fd); + if (!status) goto gdsc_error; - if (be32toh(data) != DBC_WELCOME) + status = extract_packed_buffer(&in_pbuf, &data, sizeof(uint32_t), true); + if (!status) goto gdsc_error; + + if (data != DBC_WELCOME) { log_variadic_message(LMT_ERROR, _("The server '%s' did not welcome us!"), desc); - goto gdcs_error; + goto gdsc_error; } - if (!safe_recv(client->fd, &data, sizeof(uint32_t), 0)) - goto gdcs_error; + status = extract_packed_buffer(&in_pbuf, &data, sizeof(uint32_t), true); + if (!status) goto gdsc_error; - error = be32toh(data); + error = data; switch (error) { @@ -432,25 +443,25 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc) case DBE_WRONG_VERSION: log_variadic_message(LMT_ERROR, _("The server '%s' does not use our protocol version (0x%08x)..."), desc, CDB_PROTOCOL_VERSION); - goto gdcs_error; + goto gdsc_error; break; case DBE_XML_VERSION_ERROR: log_variadic_message(LMT_ERROR, _("The archive from the server '%s' does not use our protocol version (0x%08x)..."), desc, CDB_PROTOCOL_VERSION); - goto gdcs_error; + goto gdsc_error; break; case DBE_DB_LOADING_ERROR: log_variadic_message(LMT_ERROR, _("The server '%s' got into troubles while loading the database...."), desc); - goto gdcs_error; + goto gdsc_error; break; default: log_variadic_message(LMT_ERROR, _("The server '%s' has run into an error (%u)..."), desc, error); - goto gdcs_error; + goto gdsc_error; break; } @@ -460,13 +471,22 @@ static bool g_db_client_start_common(GDbClient *client, const char *desc) { log_variadic_message(LMT_ERROR, _("Failed to start a listening thread for the server '%s'!"), desc); - goto gdcs_error; + goto gdsc_error; } + exit_packed_buffer(&out_pbuf); + exit_packed_buffer(&in_pbuf); + return true; + gdsc_error: + + exit_packed_buffer(&in_pbuf); + gdcs_error: + exit_packed_buffer(&out_pbuf); + unset_rle_string(&user); close(client->fd); @@ -493,7 +513,8 @@ static void *g_db_client_update(GDbClient *client) { struct pollfd fds; /* Surveillance des flux */ int ret; /* Bilan d'un appel */ - uint32_t val32; /* Valeur sur 32 bits */ + packed_buffer in_pbuf; /* Tampon de réception */ + uint32_t tmp32; /* Valeur sur 32 bits */ bool status; /* Bilan d'une opération */ uint32_t command; /* Commande de la requête */ DBError error; /* Bilan d'une commande passée */ @@ -515,19 +536,20 @@ static void *g_db_client_update(GDbClient *client) if (fds.revents & (POLLIN | POLLPRI)) { - status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0); + status = recv_packed_buffer(&in_pbuf, fds.fd); if (!status) goto gdcu_bad_exchange; - command = be32toh(val32); + status = extract_packed_buffer(&in_pbuf, &command, sizeof(uint32_t), true); + if (!status) goto gdcu_bad_exchange; switch (command) { case DBC_SAVE: - status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0); + status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true); if (!status) goto gdcu_bad_exchange; - error = be32toh(val32); + error = tmp32; if (error == DBE_NONE) log_variadic_message(LMT_INFO, _("Archive saved for binary '%s'"), @@ -540,13 +562,13 @@ static void *g_db_client_update(GDbClient *client) case DBC_COLLECTION: - status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0); + status = extract_packed_buffer(&in_pbuf, &tmp32, sizeof(uint32_t), true); if (!status) goto gdcu_bad_exchange; - collec = find_collection_in_list(client->collections, be32toh(val32)); + collec = find_collection_in_list(client->collections, tmp32); if (collec == NULL) goto gdcu_bad_exchange; - status = g_db_collection_recv(collec, fds.fd, NULL); + status = g_db_collection_unpack(collec, &in_pbuf, NULL); if (!status) goto gdcu_bad_exchange; @@ -558,12 +580,16 @@ static void *g_db_client_update(GDbClient *client) } + exit_packed_buffer(&in_pbuf); + continue; gdcu_bad_exchange: printf("Bad reception...\n"); + exit_packed_buffer(&in_pbuf); + /* TODO : close conn */ ; @@ -689,15 +715,24 @@ bool g_db_client_save(GDbClient *client) bool g_db_client_set_last_active(GDbClient *client, timestamp_t timestamp) { bool result; /* Bilan partiel à remonter */ + packed_buffer out_pbuf; /* Tampon d'émission */ + + init_packed_buffer(&out_pbuf); g_db_client_get_fd(client); - result = safe_send(client->fd, (uint32_t []) { htobe32(DBC_SET_LAST_ACTIVE) }, sizeof(uint32_t), 0); + result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_LAST_ACTIVE }, sizeof(uint32_t), true); - result &= send_timestamp(×tamp, client->fd, MSG_MORE); + if (result) + result = pack_timestamp(×tamp, &out_pbuf); g_db_client_put_fd(client); + if (result) + result = send_packed_buffer(&out_pbuf, client->fd); + + exit_packed_buffer(&out_pbuf); + return result; } diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index ebf7eb8..12194ca 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -33,7 +33,6 @@ #include "collection-int.h" #include "misc/rlestr.h" #include "../../common/extstr.h" -#include "../../common/io.h" #include "../../glibext/chrysamarshal.h" @@ -258,7 +257,7 @@ uint32_t g_db_collection_get_feature(const GDbCollection *collec) /****************************************************************************** * * * Paramètres : collec = ensemble d'éléments à considérer. * -* fd = flux ouvert en lecture pour la réception de données.* +* pbuf = paquet de données où venir puiser les infos. * * db = base de données à mettre à jour. * * * * Description : Réceptionne et traite une requête réseau pour collection. * @@ -271,25 +270,28 @@ uint32_t g_db_collection_get_feature(const GDbCollection *collec) * * ******************************************************************************/ -bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db) +bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3 *db) { bool result; /* Bilan à faire remonter */ - uint32_t val32; /* Valeur sur 32 bits */ + uint32_t tmp32; /* Valeur sur 32 bits */ bool status; /* Bilan de lecture initiale */ DBAction action; /* Commande de la requête */ GDbItem *item; /* Définition d'élément visé */ GList *found; /* Test de présence existante */ timestamp_t inactive; /* Horodatage de désactivation */ - status = safe_recv(fd, &val32, sizeof(uint32_t), 0); - if (!status) return false; + result = extend_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true); + action = tmp32; + + if (action < 0 || action >= DBA_COUNT) + result = false; - action = be32toh(val32); - if (action < 0 || action >= DBA_COUNT) return false; + if (!result) + return result; item = g_object_new(collec->type, NULL); - status = g_db_item_recv(item, fd, 0); + status = g_db_item_unpack(item, pbuf); if (!status) return false; result = false; @@ -380,7 +382,7 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db) /****************************************************************************** * * * Paramètres : collec = ensemble d'éléments à considérer. * -* fd = flux ouvert en écriture pour l'émission de données. * +* pbuf = paquet de données où venir inscrire les infos. * * action = avenir de l'élément fourni. * * item = élément de collection à sérialiser. * * * @@ -392,23 +394,22 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db) * * ******************************************************************************/ -bool g_db_collection_send(GDbCollection *collec, int fd, DBAction action, GDbItem *item) +bool g_db_collection_pack(GDbCollection *collec, packed_buffer *pbuf, DBAction action, GDbItem *item) { - bool status; /* Bilan de lecture initiale */ + bool result; /* Bilan à retourner */ - status = safe_send(fd, (uint32_t []) { htobe32(DBC_COLLECTION) }, sizeof(uint32_t), MSG_MORE); - if (!status) return false; + result = extend_packed_buffer(pbuf, (uint32_t []) { DBC_COLLECTION }, sizeof(uint32_t), true); - status = safe_send(fd, (uint32_t []) { htobe32(collec->featuring) }, sizeof(uint32_t), MSG_MORE); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint32_t []) { collec->featuring }, sizeof(uint32_t), true); - status = safe_send(fd, (uint32_t []) { htobe32(action) }, sizeof(uint32_t), MSG_MORE); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint32_t []) { action }, sizeof(uint32_t), true); - status = g_db_item_send(item, fd, 0); - if (!status) return false; + if (result) + result = g_db_item_pack(item, pbuf); - return true; + return result; } @@ -416,7 +417,7 @@ bool g_db_collection_send(GDbCollection *collec, int fd, DBAction action, GDbIte /****************************************************************************** * * * Paramètres : collec = ensemble d'éléments à considérer. * -* fd = flux ouvert en écriture pour l'émission de données. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Envoie pour mise à jour tous les éléments courants. * * * @@ -426,7 +427,7 @@ bool g_db_collection_send(GDbCollection *collec, int fd, DBAction action, GDbIte * * ******************************************************************************/ -bool g_db_collection_send_all_updates(GDbCollection *collec, int fd) +bool g_db_collection_pack_all_updates(GDbCollection *collec, packed_buffer *pbuf) { bool result; /* Bilan à renvoyer */ GList *iter; /* Boucle de parcours */ @@ -439,7 +440,7 @@ bool g_db_collection_send_all_updates(GDbCollection *collec, int fd) iter != NULL && result; iter = g_list_next(iter)) { - result = g_db_collection_send(collec, fd, DBA_ADD_ITEM, G_DB_ITEM(iter->data)); + result = g_db_collection_pack(collec, pbuf, DBA_ADD_ITEM, G_DB_ITEM(iter->data)); } @@ -1495,7 +1496,7 @@ void lock_unlock_collections(GList *list, bool write, bool lock) /****************************************************************************** * * * Paramètres : list = ensemble de collectons à traiter. * -* fd = canal de communication ouvert en lecture. * +* pbuf = paquet de données où venir puiser les infos. * * db = base de données à mettre à jour. * * * * Description : Met à jour les statuts d'activité des éléments. * @@ -1506,7 +1507,7 @@ void lock_unlock_collections(GList *list, bool write, bool lock) * * ******************************************************************************/ -bool update_activity_in_collections(GList *list, int fd, sqlite3 *db) +bool update_activity_in_collections(GList *list, packed_buffer *pbuf, sqlite3 *db) { bool result; /* Résultat global à renvoyer */ bool status; /* Bilan de lecture initiale */ @@ -1521,7 +1522,7 @@ bool update_activity_in_collections(GList *list, int fd, sqlite3 *db) /* TODO : lock ? */ - status = recv_timestamp(×tamp, fd, 0); + status = unpack_timestamp(×tamp, pbuf); if (!status) return false; inactive = TIMESTAMP_ALL_ACTIVE; diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h index 79787e3..1eb297c 100644 --- a/src/analysis/db/collection.h +++ b/src/analysis/db/collection.h @@ -33,6 +33,7 @@ #include "item.h" #include "protocol.h" +#include "../../common/packed.h" @@ -70,13 +71,13 @@ uint32_t g_db_collection_get_feature(const GDbCollection *); /* Réceptionne et traite une requête réseau pour collection. */ -bool g_db_collection_recv(GDbCollection *, int, sqlite3 *); +bool g_db_collection_unpack(GDbCollection *, packed_buffer *, sqlite3 *); /* Envoie pour traitement une requête réseau pour collection. */ -bool g_db_collection_send(GDbCollection *, int, DBAction, GDbItem *); +bool g_db_collection_pack(GDbCollection *, packed_buffer *, DBAction, GDbItem *); /* Envoie pour mise à jour tous les éléments courants. */ -bool g_db_collection_send_all_updates(GDbCollection *, int); +bool g_db_collection_pack_all_updates(GDbCollection *, packed_buffer *); @@ -154,7 +155,7 @@ void lock_unlock_collections(GList *, bool, bool); #define runlock_collections(lst) lock_unlock_collections(lst, false, false); /* Met à jour les statuts d'activité des éléments. */ -bool update_activity_in_collections(GList *, int, sqlite3 *); +bool update_activity_in_collections(GList *, packed_buffer *, sqlite3 *); diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h index a116ac2..38ad444 100644 --- a/src/analysis/db/item-int.h +++ b/src/analysis/db/item-int.h @@ -40,10 +40,10 @@ typedef gint (* cmp_db_item_fc) (GDbItem *, GDbItem *, bool); /* Importe la définition d'une base d'éléments pour collection. */ -typedef bool (* recv_db_item_fc) (GDbItem *, int, int); +typedef bool (* unpack_db_item_fc) (GDbItem *, packed_buffer *); /* Exporte la définition d'une base d'éléments pour collection. */ -typedef bool (* send_db_item_fc) (const GDbItem *, int, int); +typedef bool (* pack_db_item_fc) (const GDbItem *, packed_buffer *); /* Construit la description humaine d'un signet sur un tampon. */ typedef void (* build_item_label_fc) (GDbItem *); @@ -84,8 +84,8 @@ struct _GDbItemClass cmp_db_item_fc cmp; /* Comparaison entre éléments */ - recv_db_item_fc recv; /* Réception depuis le réseau */ - send_db_item_fc send; /* Emission depuis le réseau */ + unpack_db_item_fc unpack; /* Réception depuis le réseau */ + pack_db_item_fc pack; /* Emission depuis le réseau */ build_item_label_fc build_label; /* Construction de description */ run_item_fc apply; /* Application de l'élément */ diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index ce08339..20276d6 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -31,7 +31,6 @@ #include "item-int.h" -#include "../../common/io.h" #include "../../core/params.h" @@ -49,10 +48,10 @@ static void g_db_item_dispose(GDbItem *); static void g_db_item_finalize(GDbItem *); /* Importe la définition d'une base d'éléments pour collection. */ -static bool g_db_item_recv_from_fd(GDbItem *, int, int); +static bool _g_db_item_unpack(GDbItem *, packed_buffer *); /* Exporte la définition d'une base d'éléments pour collection. */ -static bool g_db_item_send_to_fd(const GDbItem *, int, int); +static bool _g_db_item_pack(const GDbItem *, packed_buffer *); @@ -94,8 +93,8 @@ static void g_db_item_class_init(GDbItemClass *klass) klass->cmp = (cmp_db_item_fc)g_db_item_cmp; - klass->recv = (recv_db_item_fc)g_db_item_recv_from_fd; - klass->send = (send_db_item_fc)g_db_item_send_to_fd; + klass->unpack = (unpack_db_item_fc)_g_db_item_unpack; + klass->pack = (pack_db_item_fc)_g_db_item_pack; klass->prepare_stmt = (prepare_db_statement)_g_db_item_prepare_db_statement; klass->load = (load_db_item_fc)_g_db_item_load; @@ -290,9 +289,8 @@ gint g_db_item_compare_without_timestamp(GDbItem *a, GDbItem *b) /****************************************************************************** * * -* Paramètres : item = base d'éléments à charger. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : item = base d'éléments à charger. [OUT] * +* pbuf = paquet de données où venir puiser les infos. * * * * Description : Importe la définition d'une base d'éléments pour collection. * * * @@ -302,32 +300,30 @@ gint g_db_item_compare_without_timestamp(GDbItem *a, GDbItem *b) * * ******************************************************************************/ -static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags) +static bool _g_db_item_unpack(GDbItem *item, packed_buffer *pbuf) { - bool status; /* Bilan d'une réception */ + bool result; /* Bilan à retourner */ - status = recv_timestamp(&item->created, fd, flags); - if (!status) return false; + result = unpack_timestamp(&item->created, pbuf); - status = recv_timestamp(&item->timestamp, fd, flags); - if (!status) return false; + if (result) + result = unpack_timestamp(&item->timestamp, pbuf); - status = recv_rle_string(&item->author, fd, flags); - if (!status) return false; + if (result) + result = unpack_rle_string(&item->author, pbuf); - status = recv_rle_string(&item->tool, fd, flags); - if (!status) return false; + if (result) + result = unpack_rle_string(&item->tool, pbuf); - return true; + return result; } /****************************************************************************** * * -* Paramètres : item = base d'éléments à charger. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : item = base d'éléments à charger. [OUT] * +* pbuf = paquet de données où venir puiser les infos. * * * * Description : Importe la définition d'une base d'éléments pour collection. * * * @@ -337,11 +333,11 @@ static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags) * * ******************************************************************************/ -bool g_db_item_recv(GDbItem *item, int fd, int flags) +bool g_db_item_unpack(GDbItem *item, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ - result = G_DB_ITEM_GET_CLASS(item)->recv(item, fd, flags); + result = G_DB_ITEM_GET_CLASS(item)->unpack(item, pbuf); return result; @@ -350,9 +346,8 @@ bool g_db_item_recv(GDbItem *item, int fd, int flags) /****************************************************************************** * * -* Paramètres : item = informations à sauvegarer. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : item = informations à sauvegarer. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'une base d'éléments pour collection. * * * @@ -362,32 +357,30 @@ bool g_db_item_recv(GDbItem *item, int fd, int flags) * * ******************************************************************************/ -static bool g_db_item_send_to_fd(const GDbItem *item, int fd, int flags) +static bool _g_db_item_pack(const GDbItem *item, packed_buffer *pbuf) { - bool status; /* Bilan d'une émission */ + bool result; /* Bilan à retourner */ - status = send_timestamp(&item->created, fd, MSG_MORE | flags); - if (!status) return false; + result = pack_timestamp(&item->created, pbuf); - status = send_timestamp(&item->timestamp, fd, MSG_MORE | flags); - if (!status) return false; + if (result) + result = pack_timestamp(&item->timestamp, pbuf); - status = send_rle_string(&item->author, fd, MSG_MORE | flags); - if (!status) return false; + if (result) + result = pack_rle_string(&item->author, pbuf); - status = send_rle_string(&item->tool, fd, flags); - if (!status) return false; + if (result) + result = pack_rle_string(&item->tool, pbuf); - return true; + return result; } /****************************************************************************** * * -* Paramètres : item = informations à sauvegarer. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : item = informations à sauvegarer. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'une base d'éléments pour collection. * * * @@ -397,9 +390,9 @@ static bool g_db_item_send_to_fd(const GDbItem *item, int fd, int flags) * * ******************************************************************************/ -bool g_db_item_send(const GDbItem *item, int fd, int flags) +bool g_db_item_pack(const GDbItem *item, packed_buffer *pbuf) { - return G_DB_ITEM_GET_CLASS(item)->send(item, fd, flags); + return G_DB_ITEM_GET_CLASS(item)->pack(item, pbuf); } diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h index e31814c..286f907 100644 --- a/src/analysis/db/item.h +++ b/src/analysis/db/item.h @@ -31,6 +31,7 @@ #include "protocol.h" #include "misc/timestamp.h" +#include "../../common/packed.h" #include "../../common/sqlite.h" @@ -73,10 +74,10 @@ gint g_db_item_compare_with_timestamp(GDbItem *, GDbItem *); gint g_db_item_compare_without_timestamp(GDbItem *, GDbItem *); /* Importe la définition d'une base d'éléments pour collection. */ -bool g_db_item_recv(GDbItem *, int, int); +bool g_db_item_unpack(GDbItem *, packed_buffer *); /* Exporte la définition d'une base d'éléments pour collection. */ -bool g_db_item_send(const GDbItem *, int, int); +bool g_db_item_pack(const GDbItem *, packed_buffer *); /* Applique un élément de collection sur un binaire. */ bool g_db_item_apply(GDbItem *, GLoadedBinary *); diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 6289588..9d3b691 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -76,10 +76,10 @@ static void g_db_bookmark_finalize(GDbBookmark *); static gint g_db_bookmark_cmp(GDbBookmark *, GDbBookmark *, bool); /* Importe la définition d'un signet dans un flux réseau. */ -static bool g_db_bookmark_recv_from_fd(GDbBookmark *, int, int); +static bool g_db_bookmark_unpack(GDbBookmark *, packed_buffer *); /* Exporte la définition d'un signet dans un flux réseau. */ -static bool g_db_bookmark_send_to_fd(const GDbBookmark *, int, int); +static bool g_db_bookmark_pack(const GDbBookmark *, packed_buffer *); /* Construit la description humaine d'un signet sur un tampon. */ static void g_db_bookmark_build_label(GDbBookmark *); @@ -179,8 +179,8 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass) item->cmp = (cmp_db_item_fc)g_db_bookmark_cmp; - item->recv = (recv_db_item_fc)g_db_bookmark_recv_from_fd; - item->send = (send_db_item_fc)g_db_bookmark_send_to_fd; + item->unpack = (unpack_db_item_fc)g_db_bookmark_unpack; + item->pack = (pack_db_item_fc)g_db_bookmark_pack; item->build_label = (build_item_label_fc)g_db_bookmark_build_label; item->apply = (run_item_fc)g_db_bookmark_apply; @@ -312,8 +312,7 @@ static gint g_db_bookmark_cmp(GDbBookmark *a, GDbBookmark *b, bool with) /****************************************************************************** * * * Paramètres : bookmark = signet dont les informations sont à charger. [OUT]* -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Importe la définition d'un signet dans un flux réseau. * * * @@ -323,20 +322,19 @@ static gint g_db_bookmark_cmp(GDbBookmark *a, GDbBookmark *b, bool with) * * ******************************************************************************/ -static bool g_db_bookmark_recv_from_fd(GDbBookmark *bookmark, int fd, int flags) +static bool g_db_bookmark_unpack(GDbBookmark *bookmark, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à retourner */ - status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->recv(G_DB_ITEM(bookmark), fd, flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->unpack(G_DB_ITEM(bookmark), pbuf); - if (!recv_vmpa(&bookmark->addr, fd, flags)) - return false; + if (result) + result = unpack_vmpa(&bookmark->addr, pbuf); - if (!recv_rle_string(&bookmark->comment, fd, flags)) - return false; + if (result) + result = unpack_rle_string(&bookmark->comment, pbuf); - return true; + return result; } @@ -344,8 +342,7 @@ static bool g_db_bookmark_recv_from_fd(GDbBookmark *bookmark, int fd, int flags) /****************************************************************************** * * * Paramètres : bookmark = informations à sauvegarder. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'un signet dans un flux réseau. * * * @@ -355,20 +352,19 @@ static bool g_db_bookmark_recv_from_fd(GDbBookmark *bookmark, int fd, int flags) * * ******************************************************************************/ -static bool g_db_bookmark_send_to_fd(const GDbBookmark *bookmark, int fd, int flags) +static bool g_db_bookmark_pack(const GDbBookmark *bookmark, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à retourner */ - status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->send(G_DB_ITEM(bookmark), fd, MSG_MORE | flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->pack(G_DB_ITEM(bookmark), pbuf); - if (!send_vmpa(&bookmark->addr, fd, MSG_MORE | flags)) - return false; + if (result) + result = pack_vmpa(&bookmark->addr, pbuf); - if (!send_rle_string(&bookmark->comment, fd, flags)) - return false; + if (result) + result = pack_rle_string(&bookmark->comment, pbuf); - return true; + return result; } diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index c021e44..15d541b 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -36,7 +36,6 @@ #include "../collection-int.h" #include "../item-int.h" #include "../../human/asm/lang.h" -#include "../../../common/io.h" #include "../../../common/extstr.h" #include "../../../glibext/linegen-int.h" @@ -97,10 +96,10 @@ static void g_db_comment_finalize(GDbComment *); static gint g_db_comment_cmp(GDbComment *, GDbComment *, bool); /* Importe la définition d'un commentaire dans un flux réseau. */ -static bool g_db_comment_recv_from_fd(GDbComment *, int, int); +static bool g_db_comment_unpack(GDbComment *, packed_buffer *); /* Exporte la définition d'un commentaire dans un flux réseau. */ -static bool g_db_comment_send_to_fd(const GDbComment *, int, int); +static bool g_db_comment_pack(const GDbComment *, packed_buffer *); /* Construit la description humaine d'un commentaire. */ static void g_db_comment_build_label(GDbComment *); @@ -227,8 +226,8 @@ static void g_db_comment_class_init(GDbCommentClass *klass) item->cmp = (cmp_db_item_fc)g_db_comment_cmp; - item->recv = (recv_db_item_fc)g_db_comment_recv_from_fd; - item->send = (send_db_item_fc)g_db_comment_send_to_fd; + item->unpack = (unpack_db_item_fc)g_db_comment_unpack; + item->pack = (pack_db_item_fc)g_db_comment_pack; item->build_label = (build_item_label_fc)g_db_comment_build_label; item->apply = (run_item_fc)g_db_comment_apply; @@ -443,8 +442,7 @@ static gint g_db_comment_cmp(GDbComment *a, GDbComment *b, bool with) /****************************************************************************** * * * Paramètres : comment = commentaire avec informations sont à charger. [OUT]* -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Importe la définition d'un commentaire dans un flux réseau. * * * @@ -454,37 +452,39 @@ static gint g_db_comment_cmp(GDbComment *a, GDbComment *b, bool with) * * ******************************************************************************/ -static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags) +static bool g_db_comment_unpack(GDbComment *comment, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ - uint32_t val32; /* Valeur sur 32 bits */ - uint8_t val8; /* Valeur sur 8 bits */ - - status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->recv(G_DB_ITEM(comment), fd, flags); - if (!status) return false; - - if (!recv_vmpa(&comment->addr, fd, flags)) - return false; + bool result; /* Bilan à retourner */ + uint32_t tmp32; /* Valeur sur 32 bits */ + uint8_t tmp8; /* Valeur sur 8 bits */ - status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags); - if (!status) return false; - - comment->flags = be32toh(val32); + result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->unpack(G_DB_ITEM(comment), pbuf); - if (!recv_rle_string(&comment->text, fd, flags)) - return false; + if (result) + result = unpack_vmpa(&comment->addr, pbuf); - status = safe_recv(fd, &val8, sizeof(uint8_t), MSG_WAITALL | flags); - if (!status) return false; + if (result) + { + result = extend_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true); + comment->flags = tmp32; + } - comment->inlined = val8; + if (result) + result = unpack_rle_string(&comment->text, pbuf); - status = safe_recv(fd, &val8, sizeof(uint8_t), MSG_WAITALL | flags); - if (!status) return false; + if (result) + { + result = extend_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true); + comment->inlined = tmp8; + } - comment->repeatable = val8; + if (result) + { + result = extend_packed_buffer(pbuf, &tmp8, sizeof(uint8_t), true); + comment->repeatable = tmp8; + } - return true; + return result; } @@ -492,8 +492,7 @@ static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags) /****************************************************************************** * * * Paramètres : comment = informations à sauvegarder. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'un commentaire dans un flux réseau. * * * @@ -503,29 +502,28 @@ static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags) * * ******************************************************************************/ -static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags) +static bool g_db_comment_pack(const GDbComment *comment, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à retourner */ - status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->send(G_DB_ITEM(comment), fd, MSG_MORE | flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_comment_parent_class)->pack(G_DB_ITEM(comment), pbuf); - if (!send_vmpa(&comment->addr, fd, MSG_MORE | flags)) - return false; + if (result) + result = pack_vmpa(&comment->addr, pbuf); - status = safe_send(fd, (uint32_t []) { htobe32(comment->flags) }, sizeof(uint32_t), MSG_MORE | flags); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint32_t []) { comment->flags }, sizeof(uint32_t), true); - if (!send_rle_string(&comment->text, fd, MSG_MORE | flags)) - return false; + if (result) + result = pack_rle_string(&comment->text, pbuf); - status = safe_send(fd, (uint8_t []) { (uint8_t)comment->inlined }, sizeof(uint8_t), MSG_MORE | flags); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint8_t []) { comment->inlined }, sizeof(uint8_t), true); - status = safe_send(fd, (uint8_t []) { (uint8_t)comment->repeatable }, sizeof(uint8_t), flags); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint8_t []) { comment->repeatable }, sizeof(uint8_t), true); - return true; + return result; } diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c index c781170..ddbcab1 100644 --- a/src/analysis/db/items/move.c +++ b/src/analysis/db/items/move.c @@ -35,7 +35,6 @@ #include "../collection-int.h" #include "../item-int.h" -#include "../../../common/io.h" #include "../../../gui/editem.h" #include "../../../gtkext/gtkdisplaypanel.h" @@ -81,10 +80,10 @@ static void g_db_move_finalize(GDbMove *); static gint g_db_move_cmp(GDbMove *, GDbMove *, bool); /* Importe la définition d'un déplacement depuis un flux réseau. */ -static bool g_db_move_recv_from_fd(GDbMove *, int, int); +static bool g_db_move_unpack(GDbMove *, packed_buffer *); /* Exporte la définition d'un déplacement dans un flux réseau. */ -static bool g_db_move_send_to_fd(const GDbMove *, int, int); +static bool g_db_move_pack(const GDbMove *, packed_buffer *); /* Construit la description humaine d'un déplacement. */ static void g_db_move_build_label(GDbMove *); @@ -185,8 +184,8 @@ static void g_db_move_class_init(GDbMoveClass *klass) item->cmp = (cmp_db_item_fc)g_db_move_cmp; - item->recv = (recv_db_item_fc)g_db_move_recv_from_fd; - item->send = (send_db_item_fc)g_db_move_send_to_fd; + item->unpack = (unpack_db_item_fc)g_db_move_unpack; + item->pack = (pack_db_item_fc)g_db_move_pack; item->build_label = (build_item_label_fc)g_db_move_build_label; item->apply = (run_item_fc)g_db_move_apply; @@ -314,9 +313,8 @@ static gint g_db_move_cmp(GDbMove *a, GDbMove *b, bool with) /****************************************************************************** * * -* Paramètres : move = bascule d'affichage aux infos à charger. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : move = bascule d'affichage aux infos à charger. [OUT] * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Importe la définition d'un déplacement depuis un flux réseau.* * * @@ -326,29 +324,27 @@ static gint g_db_move_cmp(GDbMove *a, GDbMove *b, bool with) * * ******************************************************************************/ -static bool g_db_move_recv_from_fd(GDbMove *move, int fd, int flags) +static bool g_db_move_unpack(GDbMove *move, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à retourner */ - status = G_DB_ITEM_CLASS(g_db_move_parent_class)->recv(G_DB_ITEM(move), fd, flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_move_parent_class)->unpack(G_DB_ITEM(move), pbuf); - if (!recv_vmpa(&move->src, fd, flags)) - return false; + if (result) + result = pack_vmpa(&move->src, pbuf); - if (!recv_vmpa(&move->dest, fd, flags)) - return false; + if (result) + result = pack_vmpa(&move->dest, pbuf); - return true; + return result; } /****************************************************************************** * * -* Paramètres : move = bascule d'affichage aux infos à sauvegarder. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : move = bascule d'affichage aux infos à sauvegarder. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'un déplacement dans un flux réseau. * * * @@ -358,20 +354,19 @@ static bool g_db_move_recv_from_fd(GDbMove *move, int fd, int flags) * * ******************************************************************************/ -static bool g_db_move_send_to_fd(const GDbMove *move, int fd, int flags) +static bool g_db_move_pack(const GDbMove *move, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à retourner */ - status = G_DB_ITEM_CLASS(g_db_move_parent_class)->send(G_DB_ITEM(move), fd, MSG_MORE | flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_move_parent_class)->pack(G_DB_ITEM(move), pbuf); - if (!send_vmpa(&move->src, fd, MSG_MORE | flags)) - return false; + if (result) + result = pack_vmpa(&move->src, pbuf); - if (!send_vmpa(&move->dest, fd, flags)) - return false; + if (result) + result = pack_vmpa(&move->dest, pbuf); - return true; + return result; } diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index 5a03e8e..01c1910 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -34,9 +34,6 @@ #include "../collection-int.h" #include "../item-int.h" -#include "../../../common/io.h" - - @@ -81,10 +78,10 @@ static void g_db_switcher_finalize(GDbSwitcher *); static gint g_db_switcher_cmp(GDbSwitcher *, GDbSwitcher *, bool); /* Importe la définition d'un signet depuis un flux réseau. */ -static bool g_db_switcher_recv_from_fd(GDbSwitcher *, int, int); +static bool g_db_switcher_unpack(GDbSwitcher *, packed_buffer *); /* Exporte la définition d'un signet dans un flux réseau. */ -static bool g_db_switcher_send_to_fd(const GDbSwitcher *, int, int); +static bool g_db_switcher_pack(const GDbSwitcher *, packed_buffer *); /* Construit la description humaine d'un signet sur un tampon. */ static void g_db_switcher_build_label(GDbSwitcher *); @@ -185,8 +182,8 @@ static void g_db_switcher_class_init(GDbSwitcherClass *klass) item->cmp = (cmp_db_item_fc)g_db_switcher_cmp; - item->recv = (recv_db_item_fc)g_db_switcher_recv_from_fd; - item->send = (send_db_item_fc)g_db_switcher_send_to_fd; + item->unpack = (unpack_db_item_fc)g_db_switcher_unpack; + item->pack = (pack_db_item_fc)g_db_switcher_pack; item->build_label = (build_item_label_fc)g_db_switcher_build_label; item->apply = (run_item_fc)g_db_switcher_apply; @@ -358,8 +355,7 @@ static gint g_db_switcher_cmp(GDbSwitcher *a, GDbSwitcher *b, bool with) /****************************************************************************** * * * Paramètres : switcher = bascule d'affichage aux infos à charger. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Importe la définition d'un signet depuis un flux réseau. * * * @@ -369,31 +365,33 @@ static gint g_db_switcher_cmp(GDbSwitcher *a, GDbSwitcher *b, bool with) * * ******************************************************************************/ -static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags) +static bool g_db_switcher_unpack(GDbSwitcher *switcher, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ - uint32_t val32; /* Valeur sur 32 bits */ + bool result; /* Bilan à retourner */ + uint32_t tmp32; /* Valeur sur 32 bits */ - status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->recv(G_DB_ITEM(switcher), fd, flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->unpack(G_DB_ITEM(switcher), pbuf); - if (!recv_vmpa(&switcher->addr, fd, flags)) - return false; - - status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags); - if (!status) return false; + if (result) + result = unpack_vmpa(&switcher->addr, pbuf); - switcher->index = be32toh(val32); + if (result) + { + result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true); + switcher->index = tmp32; + } - status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags); - if (!status) return false; + if (result) + { + result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true); + switcher->display = tmp32; - switcher->display = be32toh(val32); + if (switcher->display > IOD_COUNT) + result = false; - if (switcher->display > IOD_COUNT) - return false; + } - return true; + return result; } @@ -401,8 +399,7 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags) /****************************************************************************** * * * Paramètres : switcher = bascule d'affichage aux infos à sauvegarder. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'une bascule d'affichage d'opérande. * * * @@ -412,23 +409,22 @@ static bool g_db_switcher_recv_from_fd(GDbSwitcher *switcher, int fd, int flags) * * ******************************************************************************/ -static bool g_db_switcher_send_to_fd(const GDbSwitcher *switcher, int fd, int flags) +static bool g_db_switcher_pack(const GDbSwitcher *switcher, packed_buffer *pbuf) { - bool status; /* Bilan d'opération initiale */ + bool result; /* Bilan à retourner */ - status = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->send(G_DB_ITEM(switcher), fd, MSG_MORE | flags); - if (!status) return false; + result = G_DB_ITEM_CLASS(g_db_switcher_parent_class)->pack(G_DB_ITEM(switcher), pbuf); - if (!send_vmpa(&switcher->addr, fd, MSG_MORE | flags)) - return false; + if (result) + result = pack_vmpa(&switcher->addr, pbuf); - status = safe_send(fd, (uint32_t []) { htobe32(switcher->index) }, sizeof(uint32_t), MSG_MORE | flags); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint32_t []) { switcher->index }, sizeof(uint32_t), true); - status = safe_send(fd, (uint32_t []) { htobe32(switcher->display) }, sizeof(uint32_t), flags); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint32_t []) { switcher->display }, sizeof(uint32_t), true); - return true; + return result; } diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c index 2f06542..39e2d99 100644 --- a/src/analysis/db/misc/rlestr.c +++ b/src/analysis/db/misc/rlestr.c @@ -24,15 +24,11 @@ #include "rlestr.h" -#include #include #include #include -#include "../../../common/io.h" - - /****************************************************************************** * * @@ -162,9 +158,8 @@ int cmp_rle_string(const rle_string *s1, const rle_string *s2) /****************************************************************************** * * -* Paramètres : str = informations à constituer. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options de réception supplémentaires. * +* Paramètres : str = informations à constituer. [OUT] * +* pbuf = paquet de données où venir puiser les infos. * * * * Description : Importe la définition d'une chaîne de caractères. * * * @@ -174,44 +169,41 @@ int cmp_rle_string(const rle_string *s1, const rle_string *s2) * * ******************************************************************************/ -bool recv_rle_string(rle_string *str, int fd, int flags) +bool unpack_rle_string(rle_string *str, packed_buffer *pbuf) { - uint32_t val32; /* Valeur sur 32 bits */ - bool status; /* Bilan d'une opération */ + bool result; /* Bilan à retourner */ + uint32_t tmp32; /* Valeur sur 32 bits */ str->data = NULL; str->length = 0; - status = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL | flags); - if (!status) return false; + result = extract_packed_buffer(pbuf, &tmp32, sizeof(uint32_t), true); - str->length = be32toh(val32); + str->length = tmp32; - if (str->length > 0) + if (result && str->length > 0) { str->data = (char *)malloc(str->length + 1); - status = safe_recv(fd, str->data, str->length + 1, MSG_WAITALL | flags); - if (!status) - { + result = extract_packed_buffer(pbuf, str->data, str->length + 1, false); + + if (!result) unset_rle_string(str); - return false; - } - str->data[str->length] = '\0'; + else + str->data[str->length] = '\0'; } - return true; + return result; } /****************************************************************************** * * -* Paramètres : str = informations à sauvegarer. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : str = informations à sauvegarer. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'une chaîne de caractères. * * * @@ -221,20 +213,16 @@ bool recv_rle_string(rle_string *str, int fd, int flags) * * ******************************************************************************/ -bool send_rle_string(const rle_string *str, int fd, int flags) +bool pack_rle_string(const rle_string *str, packed_buffer *pbuf) { - bool status; /* Bilan d'une opération */ + bool result; /* Bilan à retourner */ - status = safe_send(fd, (uint32_t []) { htobe32(str->length) }, sizeof(uint32_t), MSG_MORE | flags); - if (!status) return false; + result = extend_packed_buffer(pbuf, (uint32_t []) { str->length }, sizeof(uint32_t), true); - if (str->length > 0) - { - status = safe_send(fd, str->data, str->length + 1, flags); - if (!status) return false; - } + if (result && str->length > 0) + result = extend_packed_buffer(pbuf, str->data, str->length + 1, false); - return true; + return result; } diff --git a/src/analysis/db/misc/rlestr.h b/src/analysis/db/misc/rlestr.h index 01f37e6..be76f17 100644 --- a/src/analysis/db/misc/rlestr.h +++ b/src/analysis/db/misc/rlestr.h @@ -30,6 +30,7 @@ #include +#include "../../../common/packed.h" #include "../../../common/sqlite.h" @@ -66,10 +67,10 @@ void unset_rle_string(rle_string *); int cmp_rle_string(const rle_string *, const rle_string *); /* Importe la définition d'une chaîne de caractères. */ -bool recv_rle_string(rle_string *, int, int); +bool unpack_rle_string(rle_string *, packed_buffer *); /* Exporte la définition d'une chaîne de caractères. */ -bool send_rle_string(const rle_string *, int, int); +bool pack_rle_string(const rle_string *, packed_buffer *); diff --git a/src/analysis/db/misc/timestamp.c b/src/analysis/db/misc/timestamp.c index 6c7a47f..aa9f758 100644 --- a/src/analysis/db/misc/timestamp.c +++ b/src/analysis/db/misc/timestamp.c @@ -24,15 +24,11 @@ #include "timestamp.h" -#include #include #include #include -#include "../../../common/io.h" - - /****************************************************************************** * * @@ -117,8 +113,7 @@ int cmp_timestamp(const timestamp_t *t1, const timestamp_t *t2) /****************************************************************************** * * * Paramètres : timestamp = informations à constituer. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options de réception supplémentaires.* +* pbuf = paquet de données où venir puiser les infos. * * * * Description : Importe la définition d'un horodatage. * * * @@ -128,17 +123,13 @@ int cmp_timestamp(const timestamp_t *t1, const timestamp_t *t2) * * ******************************************************************************/ -bool recv_timestamp(timestamp_t *timestamp, int fd, int flags) +bool unpack_timestamp(timestamp_t *timestamp, packed_buffer *pbuf) { - uint64_t val64; /* Valeur sur 64 bits */ - bool status; /* Bilan d'une opération */ + bool result; /* Bilan à retourner */ - status = safe_recv(fd, &val64, sizeof(uint64_t), MSG_WAITALL | flags); - if (!status) return false; + result = extract_packed_buffer(pbuf, (uint64_t *)timestamp, sizeof(uint64_t), true); - *timestamp = be64toh(val64); - - return true; + return result; } @@ -146,8 +137,7 @@ bool recv_timestamp(timestamp_t *timestamp, int fd, int flags) /****************************************************************************** * * * Paramètres : timestamp = informations à sauvegarer. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Exporte la définition d'un horodatage. * * * @@ -157,14 +147,13 @@ bool recv_timestamp(timestamp_t *timestamp, int fd, int flags) * * ******************************************************************************/ -bool send_timestamp(const timestamp_t *timestamp, int fd, int flags) +bool pack_timestamp(const timestamp_t *timestamp, packed_buffer *pbuf) { - bool status; /* Bilan d'une opération */ + bool result; /* Bilan à retourner */ - status = safe_send(fd, (uint64_t []) { htobe64(*timestamp) }, sizeof(uint64_t), flags); - if (!status) return false; + result = extend_packed_buffer(pbuf, (uint64_t *)timestamp, sizeof(uint64_t), true); - return true; + return result; } diff --git a/src/analysis/db/misc/timestamp.h b/src/analysis/db/misc/timestamp.h index 5d4f2f1..14a1fb5 100644 --- a/src/analysis/db/misc/timestamp.h +++ b/src/analysis/db/misc/timestamp.h @@ -29,6 +29,7 @@ #include +#include "../../../common/packed.h" #include "../../../common/sqlite.h" @@ -52,10 +53,10 @@ bool timestamp_is_younger(timestamp_t, timestamp_t); int cmp_timestamp(const timestamp_t *, const timestamp_t *); /* Importe la définition d'un horodatage. */ -bool recv_timestamp(timestamp_t *, int, int); +bool unpack_timestamp(timestamp_t *, packed_buffer *); /* Exporte la définition d'un horodatage. */ -bool send_timestamp(const timestamp_t *, int, int); +bool pack_timestamp(const timestamp_t *, packed_buffer *); diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c index 1621ed7..748af4e 100644 --- a/src/analysis/db/server.c +++ b/src/analysis/db/server.c @@ -478,12 +478,15 @@ static void *g_db_server_listener(GDbServer *server) char *peer_name; /* Désignation du correspondant*/ DBError error; /* Validation de la connexion */ GCdbArchive *archive; /* Destinataire final du client*/ + packed_buffer in_pbuf; /* Tampon de réception */ + bool status; /* Bilan d'une opération */ uint32_t cmd; /* Commande initiale lue */ uint32_t version; /* Version du client lue */ rle_string hash; /* Empreinte du binaire visé */ rle_string user; /* Nom d'utilisateur du client */ unsigned char sig[RSA_USED_SIZE]; /* Signature effectuée */ GList *iter; /* Boucle de parcours */ + packed_buffer out_pbuf; /* Tampon d'émission */ fds.fd = server->fd; fds.events = POLLIN | POLLPRI; @@ -540,7 +543,17 @@ static void *g_db_server_listener(GDbServer *server) * Tout ceci est à synchroniser avec la fonction g_db_client_start(). */ - if (!safe_recv(fd, &cmd, sizeof(uint32_t), 0)) + status = recv_packed_buffer(&in_pbuf, fd); + if (!status) + { + log_variadic_message(LMT_ERROR, _("Error while getting the initial packet from '%s'..."), + peer_name); + error = DBE_BAD_EXCHANGE; + goto gdsl_error_sending; + } + + status = extract_packed_buffer(&in_pbuf, &cmd, sizeof(uint32_t), true); + if (!status) { log_variadic_message(LMT_ERROR, _("Error while getting the initial command from '%s'..."), peer_name); @@ -548,7 +561,8 @@ static void *g_db_server_listener(GDbServer *server) goto gdsl_error_sending; } - if (!safe_recv(fd, &version, sizeof(uint32_t), 0)) + status = extract_packed_buffer(&in_pbuf, &version, sizeof(uint32_t), true); + if (!status) { log_variadic_message(LMT_ERROR, _("Error while getting the protocol version from '%s'..."), peer_name); @@ -556,7 +570,8 @@ static void *g_db_server_listener(GDbServer *server) goto gdsl_error_sending; } - if (!recv_rle_string(&hash, fd, 0)) + status = unpack_rle_string(&hash, &in_pbuf); + if (!status) { log_variadic_message(LMT_ERROR, _("Error while getting the binary hash from '%s'..."), peer_name); @@ -564,7 +579,8 @@ static void *g_db_server_listener(GDbServer *server) goto gdsl_error_sending; } - if (!recv_rle_string(&user, fd, 0)) + status = unpack_rle_string(&user, &in_pbuf); + if (!status) { log_variadic_message(LMT_ERROR, _("Error while getting the user name from '%s'..."), peer_name); @@ -572,7 +588,8 @@ static void *g_db_server_listener(GDbServer *server) goto gdsl_error_sending; } - if (!safe_recv(fd, sig, RSA_USED_SIZE, 0)) + status = extract_packed_buffer(&in_pbuf, sig, RSA_USED_SIZE, false); + if (!status) { log_variadic_message(LMT_ERROR, _("Error while getting the signature from '%s'..."), peer_name); @@ -580,7 +597,7 @@ static void *g_db_server_listener(GDbServer *server) goto gdsl_error_sending; } - if (be32toh(cmd) != DBC_HELO) + if (cmd != DBC_HELO) { log_variadic_message(LMT_ERROR, _("The client from '%s' did not introduce itself!"), peer_name); @@ -588,7 +605,7 @@ static void *g_db_server_listener(GDbServer *server) goto gdsl_error_sending; } - if (be32toh(version) != CDB_PROTOCOL_VERSION) + if (version != CDB_PROTOCOL_VERSION) { log_variadic_message(LMT_ERROR, _("The client from '%s' does not use the same protocol: 0x%08x vs 0x%08x..."), peer_name, be32toh(version), CDB_PROTOCOL_VERSION); @@ -647,11 +664,20 @@ static void *g_db_server_listener(GDbServer *server) gdsl_error_sending: - if (!safe_send(fd, (uint32_t []) { htobe32(DBC_WELCOME) }, sizeof(uint32_t), MSG_MORE)) - goto gdsl_error; + exit_packed_buffer(&in_pbuf); - if (!safe_send(fd, (uint32_t []) { htobe32(error) }, sizeof(uint32_t), 0)) - goto gdsl_error; + init_packed_buffer(&out_pbuf); + + status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_WELCOME }, sizeof(uint32_t), true); + if (!status) goto gdsl_error; + + status = extend_packed_buffer(&out_pbuf, (uint32_t []) { error }, sizeof(uint32_t), true); + if (!status) goto gdsl_error; + + status = send_packed_buffer(&out_pbuf, fd); + if (!status) goto gdsl_error; + + exit_packed_buffer(&out_pbuf); /** * L'ajout dans la liste des clients connectés provoque un envoie de mises à jour. @@ -679,6 +705,8 @@ static void *g_db_server_listener(GDbServer *server) gdsl_error: + exit_packed_buffer(&out_pbuf); + free(peer_name); exit_rle_string(&hash); diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index c32c836..27262d1 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -34,9 +34,6 @@ #include -#include "../common/io.h" - - /* ---------------------- DEFINITION D'UNE POSITION EN MEMOIRE ---------------------- */ @@ -347,9 +344,8 @@ phys_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) /****************************************************************************** * * -* Paramètres : addr = élément à venir lire. [OUT] * -* fd = flux ouvert en lecture pour l'importation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : addr = élément à venir lire. [OUT] * +* pbuf = paquet de données où venir puiser les infos. * * * * Description : Lit la définition d'une adresse depuis un flux réseau. * * * @@ -359,31 +355,24 @@ phys_t compute_vmpa_diff(const vmpa2t *a, const vmpa2t *b) * * ******************************************************************************/ -bool recv_vmpa(vmpa2t *addr, int fd, int flags) +bool unpack_vmpa(vmpa2t *addr, packed_buffer *pbuf) { - virt_t val64; /* Valeur sur 64 bits */ - bool status; /* Bilan d'une réception */ - - status = safe_recv(fd, &val64, sizeof(uint64_t), MSG_WAITALL | flags); - if (!status) return false; - - addr->physical = be64toh(val64); + bool result; /* Bilan à retourner */ - status = safe_recv(fd, &val64, sizeof(uint64_t), MSG_WAITALL | flags); - if (!status) return false; + result = extract_packed_buffer(pbuf, (uint64_t *)&addr->physical, sizeof(uint64_t), true); - addr->virtual = be64toh(val64); + if (result) + result = extract_packed_buffer(pbuf, (uint64_t *)&addr->virtual, sizeof(uint64_t), true); - return true; + return result; } /****************************************************************************** * * -* Paramètres : addr = élément à venir écrire. * -* fd = flux ouvert en écriture pour l'exportation. * -* flags = éventuelles options d'envoi supplémentaires. * +* Paramètres : addr = élément à venir écrire. * +* pbuf = paquet de données où venir inscrire les infos. * * * * Description : Ecrit la définition d'une adresse dans un flux réseau. * * * @@ -393,17 +382,16 @@ bool recv_vmpa(vmpa2t *addr, int fd, int flags) * * ******************************************************************************/ -bool send_vmpa(const vmpa2t *addr, int fd, int flags) +bool pack_vmpa(const vmpa2t *addr, packed_buffer *pbuf) { - bool status; /* Bilan d'une émission */ + bool result; /* Bilan à retourner */ - status = safe_send(fd, (uint64_t []) { htobe64(addr->physical) }, sizeof(uint64_t), MSG_MORE | flags); - if (!status) return false; + result = extend_packed_buffer(pbuf, (uint64_t *)&addr->physical, sizeof(uint64_t), true); - status = safe_send(fd, (uint64_t []) { htobe64(addr->virtual) }, sizeof(uint64_t), flags); - if (!status) return false; + if (result) + result = extend_packed_buffer(pbuf, (uint64_t *)&addr->virtual, sizeof(uint64_t), true); - return true; + return result; } diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 6305f79..3bfb40c 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -33,6 +33,7 @@ #include "archbase.h" #include "../common/cpp.h" +#include "../common/packed.h" #include "../common/sqlite.h" @@ -122,10 +123,10 @@ void align_vmpa(vmpa2t *, phys_t); phys_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *); /* Lit la définition d'une adresse depuis un flux réseau. */ -bool recv_vmpa(vmpa2t *, int, int); +bool unpack_vmpa(vmpa2t *, packed_buffer *); /* Ecrit la définition d'une adresse dans un flux réseau. */ -bool send_vmpa(const vmpa2t *, int, int); +bool pack_vmpa(const vmpa2t *, packed_buffer *); /* Transforme une adresse physique en chaîne de caractères. */ char *vmpa2_phys_to_string(const vmpa2t *, MemoryDataSize, char [VMPA_MAX_LEN], size_t *); diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 02c1718..b4d1a5b 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -15,6 +15,7 @@ libcommon_la_SOURCES = \ leb128.h leb128.c \ macros.h \ net.h net.c \ + packed.h packed.c \ pathname.h pathname.c \ shuffle.h shuffle.c \ sort.h sort.c \ diff --git a/src/common/packed.c b/src/common/packed.c new file mode 100644 index 0000000..39df330 --- /dev/null +++ b/src/common/packed.c @@ -0,0 +1,300 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * packed.c - regroupement de bribes de paquets réseau + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "packed.h" + + +#include +#include +#include +#include + + + +/* Taille d'allocation en cas de besoin */ +#define PACKET_BLOCK_SIZE 1000 + + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à initialiser. [OUT] * +* * +* Description : Intialise un paquet réseau pour une constitution. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void init_packed_buffer(packed_buffer *pbuf) +{ + pbuf->allocated = PACKET_BLOCK_SIZE; + pbuf->data = malloc(pbuf->allocated * sizeof(uint8_t)); + + pbuf->used = 0; + pbuf->pos = sizeof(uint32_t); + + assert(pbuf->pos <= pbuf->allocated); + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à libérer. * +* * +* Description : Efface les données contenues par un paquet réseau. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void exit_packed_buffer(packed_buffer *pbuf) +{ + free(pbuf->data); + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à compléter. * +* buf = nouvelles données à ajouter. * +* len = quantité de ces données. * +* hton = indique si une conversion est à réaliser. * +* * +* Description : Ajoute des données à un paquet en amont à un envoi. * +* * +* Retour : true. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool extend_packed_buffer(packed_buffer *pbuf, const void *buf, size_t len, bool hton) +{ + uint16_t tmp16; /* Valeur intermédiaire 16b */ + uint32_t tmp32; /* Valeur intermédiaire 32b */ + uint64_t tmp64; /* Valeur intermédiaire 64b */ + + /* Réallocation nécessaire ? */ + + while ((pbuf->pos + len) > pbuf->allocated) + { + pbuf->allocated += PACKET_BLOCK_SIZE; + pbuf->data = realloc(pbuf->data, pbuf->allocated * sizeof(uint8_t)); + } + + /* Conversion au formalisme du réseau */ + + if (!hton) + goto skip_conversion; + + switch (len) + { + case 1: + *((uint8_t *)(pbuf->data + pbuf->pos)) = *((uint8_t *)buf); + break; + + case 2: + tmp16 = htobe16(*(uint16_t *)buf); + *((uint16_t *)(pbuf->data + pbuf->pos)) = tmp16; + break; + + case 4: + tmp32 = htobe32(*(uint32_t *)buf); + *((uint32_t *)(pbuf->data + pbuf->pos)) = tmp32; + break; + + case 8: + tmp64 = htobe64(*(uint64_t *)buf); + *((uint64_t *)(pbuf->data + pbuf->pos)) = tmp64; + break; + + default: + + skip_conversion: + + /** + * Dans ce cas de figure, c'est à l'appelant de s'assurer que la + * conversion a bien été réalisée. + */ + assert(!hton); + + memcpy(pbuf->data + pbuf->pos, buf, len); + break; + + } + + pbuf->used += len; + pbuf->pos += len; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à consulter. * +* buf = nouvelles données à définir. * +* len = quantité de ces données. * +* ntoh = indique si une conversion est à réaliser. * +* * +* Description : Récupère des données depuis un paquet après une réception. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool extract_packed_buffer(packed_buffer *pbuf, void *buf, size_t len, bool ntoh) +{ + bool result; /* Bilan à retourner */ + uint16_t tmp16; /* Valeur intermédiaire 16b */ + uint32_t tmp32; /* Valeur intermédiaire 32b */ + uint64_t tmp64; /* Valeur intermédiaire 64b */ + + result = ((pbuf->pos + len - sizeof(uint32_t)) <= pbuf->used); + + /* Conversion au formalisme du réseau */ + + if (!ntoh) + goto skip_conversion; + + if (result) + { + switch (len) + { + case 1: + *((uint8_t *)buf) = *((uint8_t *)(pbuf->data + pbuf->pos)); + break; + + case 2: + tmp16 = be16toh(*(uint16_t *)(pbuf->data + pbuf->pos)); + *((uint16_t *)buf) = tmp16; + break; + + case 4: + tmp32 = be32toh(*(uint32_t *)(pbuf->data + pbuf->pos)); + *((uint32_t *)buf) = tmp32; + break; + + case 8: + tmp64 = be64toh(*(uint64_t *)(pbuf->data + pbuf->pos)); + *((uint64_t *)buf) = tmp64; + break; + + default: + + skip_conversion: + + /** + * Dans ce cas de figure, c'est à l'appelant de s'assurer que la + * conversion a bien été réalisée. + */ + assert(!ntoh); + + memcpy(buf, pbuf->data + pbuf->pos, len); + break; + + } + + pbuf->pos += len; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à constituer. [OUT] * +* fd = flux ouvert en lecture. * +* * +* Description : Réceptionne des données depuis un flux réseau. * +* * +* Retour : true si toutes les données ont été reçues, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool recv_packed_buffer(packed_buffer *pbuf, int fd) +{ + bool result; /* Bilan à retourner */ + uint32_t used; /* Taille de charge utile */ + + result = safe_recv(fd, &used, sizeof(uint32_t), 0); + + if (!result) + init_packed_buffer(pbuf); + + else + { + pbuf->allocated = sizeof(uint32_t) + used; + pbuf->data = malloc(pbuf->allocated * sizeof(uint8_t)); + + pbuf->used = used; + pbuf->pos = sizeof(uint32_t); + + result = safe_recv(fd, pbuf->data + pbuf->pos, used, 0); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pbuf = paquet de données à émettre. * +* fd = flux ouvert en écriture. * +* * +* Description : Envoie des données au travers un flux réseau. * +* * +* Retour : true si toutes les données ont été émises, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool send_packed_buffer(packed_buffer *pbuf, int fd) +{ + bool result; /* Bilan à retourner */ + + *((uint32_t *)pbuf->data) = pbuf->used; + + result = safe_send(fd, pbuf->data, sizeof(uint32_t) + pbuf->used, 0); + + return result; + +} diff --git a/src/common/packed.h b/src/common/packed.h new file mode 100644 index 0000000..bc038d8 --- /dev/null +++ b/src/common/packed.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * packed.h - prototypes pour le regroupement de bribes de paquets réseau + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _COMMON_PACKED_H +#define _COMMON_PACKED_H + + +#include +#include +#include + + +#include "io.h" + + + +/* Rassemblement de données d'un paquet */ +typedef struct _packed_buffer +{ + uint8_t *data; /* Données à traiter */ + size_t allocated; /* Taille allouée */ + + size_t used; /* Quantité de données utiles */ + size_t pos; /* Tête de lecture/écriture */ + +} packed_buffer; + + +/* Intialise un paquet réseau pour une constitution. */ +void init_packed_buffer(packed_buffer *); + +/* Efface les données contenues par un paquet réseau. */ +void exit_packed_buffer(packed_buffer *); + +/* Ajoute des données à un paquet en amont à un envoi. */ +bool extend_packed_buffer(packed_buffer *, const void *, size_t, bool); + +/* Récupère des données depuis un paquet après une réception. */ +bool extract_packed_buffer(packed_buffer *, void *, size_t, bool); + +/* Réceptionne des données depuis un flux réseau. */ +bool recv_packed_buffer(packed_buffer *, int); + +/* Réceptionne des données depuis un flux réseau. */ +bool recv_packed_buffer(packed_buffer *, int); + +/* Envoie des données au travers un flux réseau. */ +bool send_packed_buffer(packed_buffer *, int); + + + +#endif /* _COMMON_PACKED_H */ -- cgit v0.11.2-87-g4458