summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-05-12 11:15:23 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-05-12 11:15:23 (GMT)
commit8d71f1b7ee8714004e7ccb0ed2f0a09e8b610ce8 (patch)
treeb3cc377a047240190540f1c657b9be824b91f140
parent0386ff57e88f87286659294f12171ac7cf4da7df (diff)
Created helpers for dealing with archives.
-rw-r--r--src/analysis/db/cdb.c131
-rw-r--r--src/common/Makefile.am1
-rw-r--r--src/common/compression.c175
-rw-r--r--src/common/compression.h52
4 files changed, 259 insertions, 100 deletions
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 9479b4d..bcd3ed3 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -24,11 +24,8 @@
#include "cdb.h"
-#include <archive.h>
-#include <archive_entry.h>
#include <assert.h>
#include <errno.h>
-#include <fcntl.h>
#include <malloc.h>
#include <poll.h>
#include <pthread.h>
@@ -46,9 +43,9 @@
#include "collection.h"
#include "protocol.h"
+#include "../../common/compression.h"
#include "../../common/cpp.h"
#include "../../common/extstr.h"
-#include "../../common/io.h"
#include "../../common/pathname.h"
#include "../../common/xml.h"
#include "../../core/collections.h"
@@ -56,11 +53,6 @@
-/* Fixe le tampon pour la lecture des fichiers à inclure */
-#define ARCHIVE_RBUF_SIZE 2048
-
-
-
/* Informations relatives à un client */
typedef struct _cdb_client
{
@@ -413,8 +405,6 @@ static bool g_cdb_archive_read(GCdbArchive *archive)
bool result; /* Conclusion à retourner */
struct archive *in; /* Archive à consulter */
int ret; /* Bilan d'un appel */
- int flags; /* Propriétés à extraire */
- struct archive *out; /* Extracteur générique */
struct archive_entry *entry; /* Elément de l'archive */
const char *path; /* Désignation d'un fichier */
@@ -427,54 +417,15 @@ static bool g_cdb_archive_read(GCdbArchive *archive)
ret = archive_read_open_filename(in, archive->filename, 10240 /* ?! */);
if (ret != ARCHIVE_OK) goto gcar_exit;
- /* Propriétés à restaurer */
- flags = ARCHIVE_EXTRACT_TIME;
- flags |= ARCHIVE_EXTRACT_PERM;
- flags |= ARCHIVE_EXTRACT_ACL;
- flags |= ARCHIVE_EXTRACT_FFLAGS;
-
- out = archive_write_disk_new();
- archive_write_disk_set_options(out, flags);
- archive_write_disk_set_standard_lookup(out);
-
for (ret = archive_read_next_header(in, &entry);
ret == ARCHIVE_OK;
ret = archive_read_next_header(in, &entry))
{
- bool dump_arch_data(struct archive_entry *ent, struct archive *input, struct archive *output)
- {
- const void *buff; /* Tampon de copie */
- size_t size; /* Quantité copiée */
- __LA_INT64_T offset; /* Position de lecture */
-
- ret = archive_write_header(output, entry);
- if (ret != ARCHIVE_OK) return false;
-
- for (ret = archive_read_data_block(input, &buff, &size, &offset);
- ret == ARCHIVE_OK;
- ret = archive_read_data_block(input, &buff, &size, &offset))
- {
- ret = archive_write_data_block(output, buff, size, offset);
- if (ret != ARCHIVE_OK)
- return false;
- }
-
- if (ret != ARCHIVE_EOF)
- return false;
-
- ret = archive_write_finish_entry(output);
-
- return (ret == ARCHIVE_OK);
-
- }
-
path = archive_entry_pathname(entry);
if (strcmp(path, "desc.xml") == 0)
{
- archive_entry_set_pathname(entry, archive->xml_desc);
-
- if (!dump_arch_data(entry, in, out))
+ if (!dump_archive_entry_into_file(in, entry, archive->xml_desc))
goto gcar_exit;
if (!open_xml_file(archive->xml_desc, &archive->xdoc, &archive->context))
@@ -483,9 +434,7 @@ static bool g_cdb_archive_read(GCdbArchive *archive)
}
else if (strcmp(path, "sql.db") == 0)
{
- archive_entry_set_pathname(entry, archive->sql_db);
-
- if (!dump_arch_data(entry, in, out))
+ if (!dump_archive_entry_into_file(in, entry, archive->sql_db))
goto gcar_exit;
ret = sqlite3_open(archive->sql_db, &archive->db);
@@ -499,9 +448,6 @@ static bool g_cdb_archive_read(GCdbArchive *archive)
archive_read_close(in);
archive_read_free(in);
- archive_write_close(out);
- archive_write_free(out);
-
result = true;
gcar_exit:
@@ -528,6 +474,7 @@ DBError g_cdb_archive_write(const GCdbArchive *archive)
DBError result; /* Conclusion à retourner */
struct archive *out; /* Archive à constituer */
int ret; /* Bilan d'un appel */
+ CPError status; /* Bilan d'une compression */
result = DBE_ARCHIVE_ERROR;
@@ -538,62 +485,46 @@ DBError g_cdb_archive_write(const GCdbArchive *archive)
ret = archive_write_open_filename(out, archive->filename);
if (ret != ARCHIVE_OK) goto gcaw_exit;
- DBError add_file_to_archive(struct archive *out, const char *src, const char *path)
- {
- DBError status; /* Bilan à renvoyer */
- struct stat info; /* Informations d'origine */
- struct archive_entry *entry; /* Elément de l'archive */
- int fd; /* Flux ouvert en lecture */
- char buffer[ARCHIVE_RBUF_SIZE]; /* Tampon pour les transferts */
- ssize_t len; /* Quantité de données lues */
-
- status = DBE_ARCHIVE_ERROR;
+ status = add_file_into_archive(out, archive->xml_desc, "desc.xml");
- ret = stat(src, &info);
- if (ret != 0) return DBE_SYS_ERROR;
+ switch (status)
+ {
+ case CPE_NO_ERROR:
+ result = DBE_NONE;
+ break;
- entry = archive_entry_new();
+ case CPE_SYSTEM_ERROR:
+ result = DBE_SYS_ERROR;
+ break;
- archive_entry_copy_stat(entry, &info);
- archive_entry_set_pathname(entry, path);
+ case CPE_ARCHIVE_ERROR:
+ result = DBE_ARCHIVE_ERROR;
+ break;
- ret = archive_write_header(out, entry);
- if (ret != 0) goto afta_error;
+ }
- fd = open(src, O_RDONLY);
- if (fd == -1)
- {
- status = DBE_SYS_ERROR;
- goto afta_error;
- }
+ if (result == DBE_NONE)
+ {
+ status = add_file_into_archive(out, archive->sql_db, "sql.db");
- for (len = safe_read_partial(fd, buffer, ARCHIVE_RBUF_SIZE);
- len > 0;
- len = safe_read_partial(fd, buffer, ARCHIVE_RBUF_SIZE))
+ switch (status)
{
- if (archive_write_data(out, buffer, len) != len)
- goto afta_error;
- }
-
- close(fd);
-
- archive_entry_free(entry);
-
- return DBE_NONE;
+ case CPE_NO_ERROR:
+ result = DBE_NONE;
+ break;
- afta_error:
+ case CPE_SYSTEM_ERROR:
+ result = DBE_SYS_ERROR;
+ break;
- archive_entry_free(entry);
+ case CPE_ARCHIVE_ERROR:
+ result = DBE_ARCHIVE_ERROR;
+ break;
- return status;
+ }
}
- result = add_file_to_archive(out, archive->xml_desc, "desc.xml");
-
- if (result == DBE_NONE)
- result = add_file_to_archive(out, archive->sql_db, "sql.db");
-
gcaw_exit:
archive_write_free(out);
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index b5b008c..7a13aa8 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -6,6 +6,7 @@ libcommon_la_SOURCES = \
asm.h asm.c \
bconst.h \
bits.h bits.c \
+ compression.h compression.c \
cpp.h \
dllist.h dllist.c \
endianness.h endianness.c \
diff --git a/src/common/compression.c b/src/common/compression.c
new file mode 100644
index 0000000..d443924
--- /dev/null
+++ b/src/common/compression.c
@@ -0,0 +1,175 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * compression.c - facilités de manipulation des archives
+ *
+ * Copyright (C) 2018 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "compression.h"
+
+
+#include <fcntl.h>
+#include <stdio.h>
+
+
+#include "io.h"
+
+
+
+/* Fixe le tampon pour la lecture des fichiers à inclure */
+#define ARCHIVE_RBUF_SIZE 2048
+
+
+
+/******************************************************************************
+* *
+* Paramètres : output = archive dont le contenu est à composer. *
+* filename = chemin d'accès au fichier d'entrée. *
+* path = chemin d'accès dans l'archive. *
+* *
+* Description : Ajoute un élement à une archive. *
+* *
+* Retour : Code de retour pour l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+CPError add_file_into_archive(struct archive *output, const char *filename, const char *path)
+{
+ CPError result; /* Code de retour à renvoyer */
+ struct stat info; /* Informations d'origine */
+ int ret; /* Bilan d'un appel */
+ struct archive_entry *entry; /* Elément de l'archive */
+ int fd; /* Flux ouvert en lecture */
+ char buffer[ARCHIVE_RBUF_SIZE]; /* Tampon pour les transferts */
+ ssize_t len; /* Quantité de données lues */
+
+ result = CPE_ARCHIVE_ERROR;
+
+ ret = stat(filename, &info);
+ if (ret != 0)
+ {
+ perror("stat");
+ result = CPE_SYSTEM_ERROR;
+ goto afia_exit;
+ }
+
+ entry = archive_entry_new();
+
+ archive_entry_copy_stat(entry, &info);
+ archive_entry_set_pathname(entry, path);
+
+ ret = archive_write_header(output, entry);
+ if (ret != 0) goto afia_exit;
+
+ fd = open(filename, O_RDONLY);
+ if (fd == -1)
+ {
+ perror("open");
+ result = CPE_SYSTEM_ERROR;
+ goto afia_exit;
+ }
+
+ for (len = safe_read_partial(fd, buffer, ARCHIVE_RBUF_SIZE);
+ len > 0;
+ len = safe_read_partial(fd, buffer, ARCHIVE_RBUF_SIZE))
+ {
+ if (archive_write_data(output, buffer, len) != len)
+ goto afia_exit;
+ }
+
+ close(fd);
+
+ archive_entry_free(entry);
+
+ return CPE_NO_ERROR;
+
+ afia_exit:
+
+ archive_entry_free(entry);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : intput = archive dont le contenu est à extraire. *
+* entry = entrée de l'archive à extraire. *
+* filename = chemin d'accès au fichier de sortie. *
+* *
+* Description : Extrait un élement d'une archive. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool dump_archive_entry_into_file(struct archive *input, struct archive_entry *entry, const char *filename)
+{
+ bool result; /* Conclusion à retourner */
+ int flags; /* Propriétés à extraire */
+ struct archive *output; /* Extracteur générique */
+ int ret; /* Bilan d'un appel */
+ const void *buff; /* Tampon de copie */
+ size_t size; /* Quantité copiée */
+ __LA_INT64_T offset; /* Position de lecture */
+
+ result = false;
+
+ archive_entry_set_pathname(entry, filename);
+
+ /* Propriétés à restaurer */
+ flags = ARCHIVE_EXTRACT_TIME;
+ flags |= ARCHIVE_EXTRACT_PERM;
+ flags |= ARCHIVE_EXTRACT_ACL;
+ flags |= ARCHIVE_EXTRACT_FFLAGS;
+
+ output = archive_write_disk_new();
+ archive_write_disk_set_options(output, flags);
+ archive_write_disk_set_standard_lookup(output);
+
+ ret = archive_write_header(output, entry);
+ if (ret != ARCHIVE_OK) goto daeif_exit;
+
+ for (ret = archive_read_data_block(input, &buff, &size, &offset);
+ ret == ARCHIVE_OK;
+ ret = archive_read_data_block(input, &buff, &size, &offset))
+ {
+ ret = archive_write_data_block(output, buff, size, offset);
+ }
+
+ if (ret != ARCHIVE_EOF)
+ goto daeif_exit;
+
+ ret = archive_write_finish_entry(output);
+
+ result = (ret == ARCHIVE_OK);
+
+ daeif_exit:
+
+ archive_write_close(output);
+ archive_write_free(output);
+
+ return result;
+
+}
diff --git a/src/common/compression.h b/src/common/compression.h
new file mode 100644
index 0000000..632147a
--- /dev/null
+++ b/src/common/compression.h
@@ -0,0 +1,52 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * compression.h - prototypes pour les facilités de manipulation des archives
+ *
+ * Copyright (C) 2018 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _COMMON_COMPRESSION_H
+#define _COMMON_COMPRESSION_H
+
+
+#include <archive.h>
+#include <archive_entry.h>
+#include <stdbool.h>
+
+
+
+/* Codes de retour pour la compression */
+typedef enum _CPError
+{
+ CPE_NO_ERROR, /* Aucun souci particulier */
+ CPE_SYSTEM_ERROR, /* Le soucis vient de l'archive*/
+ CPE_ARCHIVE_ERROR /* Le soucis vient du système */
+
+} CPError;
+
+
+/* Ajoute un élement à une archive. */
+CPError add_file_into_archive(struct archive *, const char *, const char *);
+
+/* Extrait un élement d'une archive. */
+bool dump_archive_entry_into_file(struct archive *, struct archive_entry *, const char *);
+
+
+
+#endif /* _COMMON_COMPRESSION_H */