* This file is used as an example to clarify zzip api usage.
*/
+#include <sys/stat.h>
#include <zzip/zzip.h>
+#include <zzip/__string.h>
+#include <zzip/__mkdir.h>
+#include <zzip/__debug.h>
+#include <zzip/file.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "unzzipcat-zip.h"
#include "unzzipdir-zip.h"
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)
{
#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)
{
}
}
-/*
- * 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)
{
#include <io.h>
#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)
}
}
-/*
- * 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;
#include <io.h>
#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)
{
}
}
-/*
- * 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;
#include <io.h>
#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)
{
}
}
-/*
- * 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;