diff options
Diffstat (limited to 'src/common')
-rwxr-xr-x | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/extstr.h | 2 | ||||
-rw-r--r-- | src/common/pathname.c | 173 | ||||
-rw-r--r-- | src/common/pathname.h | 36 |
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 */ |