summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-12-01 20:11:27 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-12-01 20:12:35 (GMT)
commit1c9e36639b949cc765dab316825f9fec7af85a6e (patch)
tree862c1aaf89f31972930b5c938ae49cee4bb724ec /src/common
parent99f653189e448b3ff3f2f02ab876231d44fa1ce3 (diff)
Computed relative and absolute paths.
Diffstat (limited to 'src/common')
-rwxr-xr-xsrc/common/Makefile.am1
-rw-r--r--src/common/extstr.h2
-rw-r--r--src/common/pathname.c173
-rw-r--r--src/common/pathname.h36
4 files changed, 211 insertions, 1 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 7a35813..4c9c2a1 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 \
+ pathname.h pathname.c \
sqlite.h sqlite.c \
xdg.h xdg.c \
xml.h xml.c
diff --git a/src/common/extstr.h b/src/common/extstr.h
index b8bd225..6542d2f 100644
--- a/src/common/extstr.h
+++ b/src/common/extstr.h
@@ -30,7 +30,7 @@
/* Complète une chaîne de caractères avec une autre. */
-char *stradd(char *str1, const char *str2);
+char *stradd(char *, const char *);
/* Complète une chaîne de caractères avec une autre. */
char *strnadd(char *, const char *, size_t);
diff --git a/src/common/pathname.c b/src/common/pathname.c
new file mode 100644
index 0000000..181fd1f
--- /dev/null
+++ b/src/common/pathname.c
@@ -0,0 +1,173 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pathname.c - manipulation de chemins de fichiers
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "pathname.h"
+
+
+#include <assert.h>
+#include <glib.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "extstr.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = fichier servant de référence aux calculs. *
+* target = fichier absolu ciblé par la procédure. *
+* *
+* Description : Calcule le chemin relatif entre deux fichiers donnés. *
+* *
+* Retour : Chemin d'accès déterminé. *
+* *
+* Remarques : Les chemins de type 'a//b' ne sont pas supportés. *
+* *
+******************************************************************************/
+
+char *build_relative_filename(const char *ref, const char *target)
+{
+ char *result; /* Chemin à retourner */
+ size_t common; /* Taille de la partie commune */
+ const char *found; /* Séparateur suivant rencontré*/
+ size_t ref_next; /* Prochain séparateur #1 */
+ size_t target_next; /* Prochain séparateur #2 */
+ int ret; /* Bilan d'un appel */
+ unsigned int levels; /* Niveaux de décalage */
+ unsigned int i; /* Boucle de parcours #1 */
+
+ common = 0;
+
+ /* Recherche d'une base commune */
+
+ while (1)
+ {
+ found = strchr(ref + common, G_DIR_SEPARATOR);
+ if (found == NULL) break;
+
+ ref_next = found - ref;
+
+ found = strchr(target + common, G_DIR_SEPARATOR);
+ if (found == NULL) break;
+
+ target_next = found - target;
+
+ /* Comparaison rapide sur la longeur du nom */
+ if (ref_next != target_next) break;
+
+ /* Comparaison sur une portion de chemin */
+ ret = strncmp(ref + common, target + common, ref_next - common);
+ if (ret != 0) break;
+
+ common = ref_next + 1;
+
+ }
+
+ /* Décompte du décalage entre la référence et la cible */
+
+ found = ref + common;
+
+ for (levels = 0; ; levels++)
+ {
+ found = strchr(found, G_DIR_SEPARATOR);
+ if (found == NULL) break;
+
+ found++;
+
+ }
+
+ /* Construction du résultat final */
+
+ result = strdup(target + common);
+
+ for (i = 0; i < levels; i++)
+ {
+ result = strprep(result, G_DIR_SEPARATOR_S);
+ result = strprep(result, "..");
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : ref = fichier servant de référence aux calculs. *
+* target = fichier relatif ciblé par la procédure. *
+* *
+* Description : Calcule le chemin absolu d'un fichier par rapport à un autre.*
+* *
+* Retour : Chemin d'accès déterminé ou NULL en cas d'erreur. *
+* *
+* Remarques : Les chemins de type 'a//b' ne sont pas supportés. *
+* *
+******************************************************************************/
+
+char *build_absolute_filename(const char *ref, const char *target)
+{
+ char *result; /* Chemin à retourner */
+ char *last_sep; /* Dernier séparateur trouvé */
+ const char *target_base; /* Base de la relativité */
+
+ static const char upper[4] = { '.', '.', G_DIR_SEPARATOR, '\0' };
+
+ result = strdup(ref);
+
+ last_sep = strrchr(result, G_DIR_SEPARATOR);
+ assert(last_sep != NULL);
+
+ target_base = target;
+
+ /* Remontée des répertoires */
+ while (1)
+ {
+ if (strncmp(target_base, upper, 3) != 0)
+ break;
+
+ target_base += 3;
+
+ *last_sep = '\0';
+ last_sep = strrchr(result, G_DIR_SEPARATOR);
+
+ /* S'il devient impossible de remonter autant... */
+ if (last_sep == NULL) break;
+
+ }
+
+ if (last_sep == NULL)
+ {
+ free(result);
+ result = NULL;
+ }
+ else
+ {
+ *(last_sep + 1) = '\0';
+ result = stradd(result, target_base);
+ }
+
+ return result;
+
+}
diff --git a/src/common/pathname.h b/src/common/pathname.h
new file mode 100644
index 0000000..744a11b
--- /dev/null
+++ b/src/common/pathname.h
@@ -0,0 +1,36 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * pathname.h - prototypes pour la manipulation de chemins de fichiers
+ *
+ * Copyright (C) 2015 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _COMMON_PATHNAME_H
+#define _COMMON_PATHNAME_H
+
+
+/* Calcule le chemin relatif entre deux fichiers donnés. */
+char *build_relative_filename(const char *, const char *);
+
+/* Calcule le chemin absolu d'un fichier par rapport à un autre. */
+char *build_absolute_filename(const char *, const char *);
+
+
+
+#endif /* _COMMON_PATHNAME_H */