From f888547b1bb7f2354d66912fed62e2a5053b76e6 Mon Sep 17 00:00:00 2001 From: Josef Moellers Date: Fri, 12 Oct 2018 16:45:47 +0200 Subject: [PATCH 09/19] Code cleanup in "bins". --- bins/unzzip.c | 113 +++++++++++++++++++++++++++++++++++++++++ bins/unzzipcat-big.c | 91 ++------------------------------- bins/unzzipcat-mem.c | 91 ++------------------------------- bins/unzzipcat-mix.c | 116 ++----------------------------------------- bins/unzzipcat-zip.c | 116 ++----------------------------------------- 5 files changed, 125 insertions(+), 402 deletions(-) diff --git a/bins/unzzip.c b/bins/unzzip.c index f91c5eb..5426049 100644 --- a/bins/unzzip.c +++ b/bins/unzzip.c @@ -5,8 +5,14 @@ * This file is used as an example to clarify zzip api usage. */ +#include #include +#include +#include +#include +#include #include +#include #include #include "unzzipcat-zip.h" #include "unzzipdir-zip.h" @@ -32,6 +38,113 @@ static int unzzip_help(void) return 0; } +/* Functions used by unzzipcat-*.c: */ +int exitcode(int e) +{ + switch (e) + { + case ZZIP_NO_ERROR: + return EXIT_OK; + case ZZIP_OUTOFMEM: /* out of memory */ + return EXIT_ENOMEM; + case ZZIP_DIR_OPEN: /* failed to open zipfile, see errno for details */ + return EXIT_ZIP_NOT_FOUND; + case ZZIP_DIR_STAT: /* failed to fstat zipfile, see errno for details */ + case ZZIP_DIR_SEEK: /* failed to lseek zipfile, see errno for details */ + case ZZIP_DIR_READ: /* failed to read zipfile, see errno for details */ + case ZZIP_DIR_TOO_SHORT: + case ZZIP_DIR_EDH_MISSING: + return EXIT_FILEFORMAT; + case ZZIP_DIRSIZE: + return EXIT_EARLY_END_OF_FILE; + case ZZIP_ENOENT: + return EXIT_FILE_NOT_FOUND; + case ZZIP_UNSUPP_COMPR: + return EXIT_UNSUPPORTED_COMPRESSION; + case ZZIP_CORRUPTED: + case ZZIP_UNDEF: + case ZZIP_DIR_LARGEFILE: + return EXIT_FILEFORMAT; + } + return EXIT_ERRORS; +} + +/* + * NAME: remove_dotdotslash + * PURPOSE: To remove any "../" components from the given pathname + * ARGUMENTS: path: path name with maybe "../" components + * RETURNS: Nothing, "path" is modified in-place + * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! + * Also, "path" is not used after creating it. + * So modifying "path" in-place is safe to do. + */ +static inline void +remove_dotdotslash(char *path) +{ + /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ + char *dotdotslash; + int warned = 0; + + dotdotslash = path; + while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) + { + /* + * Remove only if at the beginning of the pathname ("../path/name") + * or when preceded by a slash ("path/../name"), + * otherwise not ("path../name..")! + */ + if (dotdotslash == path || dotdotslash[-1] == '/') + { + char *src, *dst; + if (!warned) + { + /* Note: the first time through the pathname is still intact */ + fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); + warned = 1; + } + /* We cannot use strcpy(), as there "The strings may not overlap" */ + for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) + ; + } + else + dotdotslash +=3; /* skip this instance to prevent infinite loop */ + } +} + +static void makedirs(const char* name) +{ + char* p = strrchr(name, '/'); + if (p) { + char* dir_name = _zzip_strndup(name, p-name); + makedirs(dir_name); + free (dir_name); + } + if (_zzip_mkdir(name, 0775) == -1 && errno != EEXIST) + { + DBG3("while mkdir %s : %s", name, strerror(errno)); + } + errno = 0; +} + +FILE* create_fopen(char* name, char* mode, int subdirs) +{ + char name_stripped[PATH_MAX]; + + strncpy(name_stripped, name, PATH_MAX); + remove_dotdotslash(name_stripped); + + if (subdirs) + { + char* p = strrchr(name_stripped, '/'); + if (p) { + char* dir_name = _zzip_strndup(name_stripped, p-name); + makedirs(dir_name); + free (dir_name); + } + } + return fopen(name_stripped, mode); +} + int main (int argc, char ** argv) { diff --git a/bins/unzzipcat-big.c b/bins/unzzipcat-big.c index 88c4d65..111ef47 100644 --- a/bins/unzzipcat-big.c +++ b/bins/unzzipcat-big.c @@ -16,10 +16,9 @@ #include "unzzipcat-zip.h" #include "unzzip-states.h" -static int exitcode(int e) -{ - return EXIT_ERRORS; -} +/* Functions in unzzip.c: */ +extern int exitcode(int); +extern FILE* create_fopen(char*, char*, int); static void unzzip_big_entry_fprint(ZZIP_ENTRY* entry, FILE* out) { @@ -53,90 +52,6 @@ static void unzzip_cat_file(FILE* disk, char* name, FILE* out) } } -/* - * NAME: remove_dotdotslash - * PURPOSE: To remove any "../" components from the given pathname - * ARGUMENTS: path: path name with maybe "../" components - * RETURNS: Nothing, "path" is modified in-place - * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! - * Also, "path" is not used after creating it. - * So modifying "path" in-place is safe to do. - */ -static inline void -remove_dotdotslash(char *path) -{ - /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ - char *dotdotslash; - int warned = 0; - - dotdotslash = path; - while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) - { - /* - * Remove only if at the beginning of the pathname ("../path/name") - * or when preceded by a slash ("path/../name"), - * otherwise not ("path../name..")! - */ - if (dotdotslash == path || dotdotslash[-1] == '/') - { - char *src, *dst; - if (!warned) - { - /* Note: the first time through the pathname is still intact */ - fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); - warned = 1; - } - /* We cannot use strcpy(), as there "The strings may not overlap" */ - for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) - ; - } - else - dotdotslash +=3; /* skip this instance to prevent infinite loop */ - } -} - -static void makedirs(const char* name) -{ - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - if (_zzip_mkdir(name, 0775) == -1 && errno != EEXIST) - { - DBG3("while mkdir %s : %s", name, strerror(errno)); - } - errno = 0; -} - -static FILE* create_fopen(char* name, char* mode, int subdirs) -{ - char *name_stripped; - FILE *fp; - int mustfree = 0; - - if ((name_stripped = strdup(name)) != NULL) - { - remove_dotdotslash(name_stripped); - name = name_stripped; - mustfree = 1; - } - if (subdirs) - { - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - } - fp = fopen(name, mode); - if (mustfree) - free(name_stripped); - return fp; -} - static int unzzip_cat (int argc, char ** argv, int extract) { diff --git a/bins/unzzipcat-mem.c b/bins/unzzipcat-mem.c index 793bde8..cfa27ab 100644 --- a/bins/unzzipcat-mem.c +++ b/bins/unzzipcat-mem.c @@ -24,10 +24,9 @@ #include #endif -static int exitcode(int e) -{ - return EXIT_ERRORS; -} +/* Functions in unzzip.c: */ +extern int exitcode(int); +extern FILE* create_fopen(char*, char*, int); static void unzzip_mem_entry_fprint(ZZIP_MEM_DISK* disk, ZZIP_MEM_ENTRY* entry, FILE* out) @@ -58,90 +57,6 @@ static void unzzip_mem_disk_cat_file(ZZIP_MEM_DISK* disk, char* name, FILE* out) } } -/* - * NAME: remove_dotdotslash - * PURPOSE: To remove any "../" components from the given pathname - * ARGUMENTS: path: path name with maybe "../" components - * RETURNS: Nothing, "path" is modified in-place - * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! - * Also, "path" is not used after creating it. - * So modifying "path" in-place is safe to do. - */ -static inline void -remove_dotdotslash(char *path) -{ - /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ - char *dotdotslash; - int warned = 0; - - dotdotslash = path; - while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) - { - /* - * Remove only if at the beginning of the pathname ("../path/name") - * or when preceded by a slash ("path/../name"), - * otherwise not ("path../name..")! - */ - if (dotdotslash == path || dotdotslash[-1] == '/') - { - char *src, *dst; - if (!warned) - { - /* Note: the first time through the pathname is still intact */ - fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); - warned = 1; - } - /* We cannot use strcpy(), as there "The strings may not overlap" */ - for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) - ; - } - else - dotdotslash +=3; /* skip this instance to prevent infinite loop */ - } -} - -static void makedirs(const char* name) -{ - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - if (_zzip_mkdir(name, 0775) == -1 && errno != EEXIST) - { - DBG3("while mkdir %s : %s", name, strerror(errno)); - } - errno = 0; -} - -static FILE* create_fopen(char* name, char* mode, int subdirs) -{ - char *name_stripped; - FILE *fp; - int mustfree = 0; - - if ((name_stripped = strdup(name)) != NULL) - { - remove_dotdotslash(name_stripped); - name = name_stripped; - mustfree = 1; - } - if (subdirs) - { - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - } - fp = fopen(name, mode); - if (mustfree) - free(name_stripped); - return fp; -} - static int unzzip_cat (int argc, char ** argv, int extract) { int done = 0; diff --git a/bins/unzzipcat-mix.c b/bins/unzzipcat-mix.c index 73b6ed6..5a32b1d 100644 --- a/bins/unzzipcat-mix.c +++ b/bins/unzzipcat-mix.c @@ -24,35 +24,9 @@ #include #endif -static int exitcode(int e) -{ - switch (e) - { - case ZZIP_NO_ERROR: - return EXIT_OK; - case ZZIP_OUTOFMEM: /* out of memory */ - return EXIT_ENOMEM; - case ZZIP_DIR_OPEN: /* failed to open zipfile, see errno for details */ - return EXIT_ZIP_NOT_FOUND; - case ZZIP_DIR_STAT: /* failed to fstat zipfile, see errno for details */ - case ZZIP_DIR_SEEK: /* failed to lseek zipfile, see errno for details */ - case ZZIP_DIR_READ: /* failed to read zipfile, see errno for details */ - case ZZIP_DIR_TOO_SHORT: - case ZZIP_DIR_EDH_MISSING: - return EXIT_FILEFORMAT; - case ZZIP_DIRSIZE: - return EXIT_EARLY_END_OF_FILE; - case ZZIP_ENOENT: - return EXIT_FILE_NOT_FOUND; - case ZZIP_UNSUPP_COMPR: - return EXIT_UNSUPPORTED_COMPRESSION; - case ZZIP_CORRUPTED: - case ZZIP_UNDEF: - case ZZIP_DIR_LARGEFILE: - return EXIT_FILEFORMAT; - } - return EXIT_ERRORS; -} +/* Functions in unzzip.c: */ +extern int exitcode(int); +extern FILE* create_fopen(char*, char*, int); static void unzzip_cat_file(ZZIP_DIR* disk, char* name, FILE* out) { @@ -69,90 +43,6 @@ static void unzzip_cat_file(ZZIP_DIR* disk, char* name, FILE* out) } } -/* - * NAME: remove_dotdotslash - * PURPOSE: To remove any "../" components from the given pathname - * ARGUMENTS: path: path name with maybe "../" components - * RETURNS: Nothing, "path" is modified in-place - * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! - * Also, "path" is not used after creating it. - * So modifying "path" in-place is safe to do. - */ -static inline void -remove_dotdotslash(char *path) -{ - /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ - char *dotdotslash; - int warned = 0; - - dotdotslash = path; - while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) - { - /* - * Remove only if at the beginning of the pathname ("../path/name") - * or when preceded by a slash ("path/../name"), - * otherwise not ("path../name..")! - */ - if (dotdotslash == path || dotdotslash[-1] == '/') - { - char *src, *dst; - if (!warned) - { - /* Note: the first time through the pathname is still intact */ - fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); - warned = 1; - } - /* We cannot use strcpy(), as there "The strings may not overlap" */ - for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) - ; - } - else - dotdotslash +=3; /* skip this instance to prevent infinite loop */ - } -} - -static void makedirs(const char* name) -{ - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - if (_zzip_mkdir(name, 0775) == -1 && errno != EEXIST) - { - DBG3("while mkdir %s : %s", name, strerror(errno)); - } - errno = 0; -} - -static FILE* create_fopen(char* name, char* mode, int subdirs) -{ - char *name_stripped; - FILE *fp; - int mustfree = 0; - - if ((name_stripped = strdup(name)) != NULL) - { - remove_dotdotslash(name_stripped); - name = name_stripped; - mustfree = 1; - } - if (subdirs) - { - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - } - fp = fopen(name, mode); - if (mustfree) - free(name_stripped); - return fp; -} - static int unzzip_cat (int argc, char ** argv, int extract) { int done = 0; diff --git a/bins/unzzipcat-zip.c b/bins/unzzipcat-zip.c index 7f7f3fa..be5e7fa 100644 --- a/bins/unzzipcat-zip.c +++ b/bins/unzzipcat-zip.c @@ -24,35 +24,9 @@ #include #endif -static int exitcode(int e) -{ - switch (e) - { - case ZZIP_NO_ERROR: - return EXIT_OK; - case ZZIP_OUTOFMEM: /* out of memory */ - return EXIT_ENOMEM; - case ZZIP_DIR_OPEN: /* failed to open zipfile, see errno for details */ - return EXIT_ZIP_NOT_FOUND; - case ZZIP_DIR_STAT: /* failed to fstat zipfile, see errno for details */ - case ZZIP_DIR_SEEK: /* failed to lseek zipfile, see errno for details */ - case ZZIP_DIR_READ: /* failed to read zipfile, see errno for details */ - case ZZIP_DIR_TOO_SHORT: - case ZZIP_DIR_EDH_MISSING: - return EXIT_FILEFORMAT; - case ZZIP_DIRSIZE: - return EXIT_EARLY_END_OF_FILE; - case ZZIP_ENOENT: - return EXIT_FILE_NOT_FOUND; - case ZZIP_UNSUPP_COMPR: - return EXIT_UNSUPPORTED_COMPRESSION; - case ZZIP_CORRUPTED: - case ZZIP_UNDEF: - case ZZIP_DIR_LARGEFILE: - return EXIT_FILEFORMAT; - } - return EXIT_ERRORS; -} +/* Functions in unzzip.c: */ +extern int exitcode(int); +extern FILE* create_fopen(char*, char*, int); static void unzzip_cat_file(ZZIP_DIR* disk, char* name, FILE* out) { @@ -69,90 +43,6 @@ static void unzzip_cat_file(ZZIP_DIR* disk, char* name, FILE* out) } } -/* - * NAME: remove_dotdotslash - * PURPOSE: To remove any "../" components from the given pathname - * ARGUMENTS: path: path name with maybe "../" components - * RETURNS: Nothing, "path" is modified in-place - * NOTE: removing "../" from the path ALWAYS shortens the path, never adds to it! - * Also, "path" is not used after creating it. - * So modifying "path" in-place is safe to do. - */ -static inline void -remove_dotdotslash(char *path) -{ - /* Note: removing "../" from the path ALWAYS shortens the path, never adds to it! */ - char *dotdotslash; - int warned = 0; - - dotdotslash = path; - while ((dotdotslash = strstr(dotdotslash, "../")) != NULL) - { - /* - * Remove only if at the beginning of the pathname ("../path/name") - * or when preceded by a slash ("path/../name"), - * otherwise not ("path../name..")! - */ - if (dotdotslash == path || dotdotslash[-1] == '/') - { - char *src, *dst; - if (!warned) - { - /* Note: the first time through the pathname is still intact */ - fprintf(stderr, "Removing \"../\" path component(s) in %s\n", path); - warned = 1; - } - /* We cannot use strcpy(), as there "The strings may not overlap" */ - for (src = dotdotslash+3, dst=dotdotslash; (*dst = *src) != '\0'; src++, dst++) - ; - } - else - dotdotslash +=3; /* skip this instance to prevent infinite loop */ - } -} - -static void makedirs(const char* name) -{ - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - if (_zzip_mkdir(name, 0775) == -1 && errno != EEXIST) - { - DBG3("while mkdir %s : %s", name, strerror(errno)); - } - errno = 0; -} - -static FILE* create_fopen(char* name, char* mode, int subdirs) -{ - char *name_stripped; - FILE *fp; - int mustfree = 0; - - if ((name_stripped = strdup(name)) != NULL) - { - remove_dotdotslash(name_stripped); - name = name_stripped; - mustfree = 1; - } - if (subdirs) - { - char* p = strrchr(name, '/'); - if (p) { - char* dir_name = _zzip_strndup(name, p-name); - makedirs(dir_name); - free (dir_name); - } - } - fp = fopen(name, mode); - if (mustfree) - free(name_stripped); - return fp; -} - static int unzzip_cat (int argc, char ** argv, int extract) { int done = 0; -- 2.22.0